static int palmas_gpio_to_irq(struct gpio_chip *chip, unsigned offset)
{
	struct palmas_gpio *palmas_gpio = to_palmas_gpio(chip);
	struct palmas *palmas = palmas_gpio->palmas;

	if (!regmap_irq_chip_get_base(palmas->irq_data))
		return -EINVAL;

	return (regmap_irq_chip_get_base(palmas->irq_data))
				+ PALMAS_GPIO_0_IRQ + offset;
}
static int device_headset_init(struct pm80x_chip *chip,
					   struct pm80x_platform_data *pdata)
{
	int ret;

	switch (chip->type) {
	case CHIP_PM800:
		headset_devs_800[0].resources =
			&headset_resources_800[0];
		headset_devs_800[0].num_resources =
			ARRAY_SIZE(headset_resources_800);
		break;
	case CHIP_PM822:
		headset_devs_800[0].resources =
			&headset_resources_822[0];
		headset_devs_800[0].num_resources =
			ARRAY_SIZE(headset_resources_822);
		break;
	default:
		return -EINVAL;
	}

	headset_devs_800[0].platform_data = pdata->headset;
	ret = mfd_add_devices(chip->dev, 0, &headset_devs_800[0],
			      ARRAY_SIZE(headset_devs_800), NULL,
			      regmap_irq_chip_get_base(chip->irq_data),
			      NULL);
	if (ret) {
		dev_err(chip->dev, "Failed to add headset subdev\n");
		return ret;
	}

	return 0;
}
static int device_battery_init(struct pm80x_chip *chip,
					   struct pm80x_platform_data *pdata)
{
	int ret;



	if (pdata) {
		bat_devs[0].platform_data = pdata->fuelgauge_data;
		bat_devs[0].pdata_size =
				sizeof(struct sec_battery_platform_data);

		ret = mfd_add_devices(chip->dev, 0, &bat_devs[0],
			      ARRAY_SIZE(bat_devs), NULL,
			      regmap_irq_chip_get_base(chip->irq_data), NULL);
	if (ret) {
		dev_err(chip->dev, "Failed to add battery subdev\n");
		return ret;
		} else {
			dev_info(chip->dev,
				"[%s]:Added mfd bat_devs\n", __func__);
		}
	}

	return 0;
}
示例#4
0
int cpcap_sense_virq(struct regmap *regmap, int virq)
{
	struct regmap_irq_chip_data *d = irq_get_chip_data(virq);
	int irq_base = regmap_irq_chip_get_base(d);

	return cpcap_sense_irq(regmap, virq - irq_base);
}
static int da9062_i2c_probe(struct i2c_client *i2c,
	const struct i2c_device_id *id)
{
	struct da9062 *chip;
	unsigned int irq_base;
	int ret;

	chip = devm_kzalloc(&i2c->dev, sizeof(*chip), GFP_KERNEL);
	if (!chip)
		return -ENOMEM;

	i2c_set_clientdata(i2c, chip);
	chip->dev = &i2c->dev;

	if (!i2c->irq) {
		dev_err(chip->dev, "No IRQ configured\n");
		return -EINVAL;
	}

	chip->regmap = devm_regmap_init_i2c(i2c, &da9062_regmap_config);
	if (IS_ERR(chip->regmap)) {
		ret = PTR_ERR(chip->regmap);
		dev_err(chip->dev, "Failed to allocate register map: %d\n",
			ret);
		return ret;
	}

	ret = da9062_clear_fault_log(chip);
	if (ret < 0)
		dev_warn(chip->dev, "Cannot clear fault log\n");

	ret = da9062_get_device_type(chip);
	if (ret)
		return ret;

	ret = regmap_add_irq_chip(chip->regmap, i2c->irq,
			IRQF_TRIGGER_LOW | IRQF_ONESHOT | IRQF_SHARED,
			-1, &da9062_irq_chip,
			&chip->regmap_irq);
	if (ret) {
		dev_err(chip->dev, "Failed to request IRQ %d: %d\n",
			i2c->irq, ret);
		return ret;
	}

	irq_base = regmap_irq_chip_get_base(chip->regmap_irq);

	ret = mfd_add_devices(chip->dev, PLATFORM_DEVID_NONE, da9062_devs,
			      ARRAY_SIZE(da9062_devs), NULL, irq_base,
			      NULL);
	if (ret) {
		dev_err(chip->dev, "Cannot register child devices\n");
		regmap_del_irq_chip(i2c->irq, chip->regmap_irq);
		return ret;
	}

	return ret;
}
static int device_dvc_init(struct pm80x_chip *chip,
					   struct pm80x_platform_data *pdata)
{
	int ret;

	ret = mfd_add_devices(chip->dev, 0, &dvc_devs[0],
			      ARRAY_SIZE(dvc_devs), NULL,
			      regmap_irq_chip_get_base(chip->irq_data), NULL);
	if (ret) {
		dev_err(chip->dev, "Failed to add dvc subdev\n");
		return ret;
	}

	return 0;
}
示例#7
0
int __devinit da9052_device_init(struct da9052 *da9052, u8 chip_id)
{
	struct da9052_pdata *pdata = da9052->dev->platform_data;
	struct irq_desc *desc;
	int ret;

	mutex_init(&da9052->auxadc_lock);
	init_completion(&da9052->done);

	if (pdata && pdata->init != NULL)
		pdata->init(da9052);

	da9052->chip_id = chip_id;

	if (!pdata || !pdata->irq_base)
		da9052->irq_base = -1;
	else
		da9052->irq_base = pdata->irq_base;

	ret = regmap_add_irq_chip(da9052->regmap, da9052->chip_irq,
				  IRQF_TRIGGER_LOW | IRQF_ONESHOT,
				  da9052->irq_base, &da9052_regmap_irq_chip,
				  &da9052->irq_data);
	if (ret < 0)
		goto regmap_err;

	da9052->irq_base = regmap_irq_chip_get_base(da9052->irq_data);

	ret = request_threaded_irq(DA9052_IRQ_ADC_EOM, NULL, da9052_auxadc_irq,
				   IRQF_TRIGGER_LOW | IRQF_ONESHOT,
				   "adc irq", da9052);
	if (ret != 0)
		dev_err(da9052->dev, "DA9052 ADC IRQ failed ret=%d\n", ret);

	ret = mfd_add_devices(da9052->dev, -1, da9052_subdev_info,
			      ARRAY_SIZE(da9052_subdev_info), NULL, 0);
	if (ret)
		goto err;

	return 0;

err:
	free_irq(DA9052_IRQ_ADC_EOM, da9052);
	mfd_remove_devices(da9052->dev);
regmap_err:
	return ret;
}
static int device_usb_init(struct pm80x_chip *chip,
				struct pm80x_platform_data *pdata)
{
	int ret;

	usb_devs[0].platform_data = pdata->usb;
	usb_devs[0].pdata_size = sizeof(struct pm80x_usb_pdata);
	ret = mfd_add_devices(chip->dev, 0, &usb_devs[0],
			      ARRAY_SIZE(usb_devs), NULL,
			      regmap_irq_chip_get_base(chip->irq_data), NULL);
	if (ret < 0) {
		dev_err(chip->dev, "Failed to add usb subdev\n");
		return ret;
	}

	return 0;
}
示例#9
0
static int da9150_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	struct da9150 *da9150;
	struct da9150_pdata *pdata = dev_get_platdata(&client->dev);
	int ret;

	da9150 = devm_kzalloc(&client->dev, sizeof(*da9150), GFP_KERNEL);
	if (!da9150)
		return -ENOMEM;

	da9150->dev = &client->dev;
	da9150->irq = client->irq;
	i2c_set_clientdata(client, da9150);

	da9150->regmap = devm_regmap_init_i2c(client, &da9150_regmap_config);
	if (IS_ERR(da9150->regmap)) {
		ret = PTR_ERR(da9150->regmap);
		dev_err(da9150->dev, "Failed to allocate register map: %d\n",
			ret);
		return ret;
	}

	da9150->irq_base = pdata ? pdata->irq_base : -1;

	ret = regmap_add_irq_chip(da9150->regmap, da9150->irq,
				  IRQF_TRIGGER_LOW | IRQF_ONESHOT,
				  da9150->irq_base, &da9150_regmap_irq_chip,
				  &da9150->regmap_irq_data);
	if (ret)
		return ret;

	da9150->irq_base = regmap_irq_chip_get_base(da9150->regmap_irq_data);
	enable_irq_wake(da9150->irq);

	ret = mfd_add_devices(da9150->dev, -1, da9150_devs,
			      ARRAY_SIZE(da9150_devs), NULL,
			      da9150->irq_base, NULL);
	if (ret) {
		dev_err(da9150->dev, "Failed to add child devices: %d\n", ret);
		regmap_del_irq_chip(da9150->irq, da9150->regmap_irq_data);
		return ret;
	}

	return 0;
}
static int device_rtc_init(struct pm80x_chip *chip,
				struct pm80x_platform_data *pdata)
{
	int ret;

	rtc_devs[0].platform_data = pdata->rtc;
	rtc_devs[0].pdata_size =
			pdata->rtc ? sizeof(struct pm80x_rtc_pdata) : 0;
	ret = mfd_add_devices(chip->dev, 0, &rtc_devs[0],
			      ARRAY_SIZE(rtc_devs), NULL,
			      regmap_irq_chip_get_base(chip->irq_data), NULL);
	if (ret) {
		dev_err(chip->dev, "Failed to add rtc subdev\n");
		return ret;
	}

	return 0;
}
示例#11
0
int da9055_device_init(struct da9055 *da9055)
{
	struct da9055_pdata *pdata = dev_get_platdata(da9055->dev);
	int ret;
	uint8_t clear_events[3] = {0xFF, 0xFF, 0xFF};

	if (pdata && pdata->init != NULL)
		pdata->init(da9055);

	if (!pdata || !pdata->irq_base)
		da9055->irq_base = -1;
	else
		da9055->irq_base = pdata->irq_base;

	ret = da9055_group_write(da9055, DA9055_REG_EVENT_A, 3, clear_events);
	if (ret < 0)
		return ret;

	ret = regmap_add_irq_chip(da9055->regmap, da9055->chip_irq,
				  IRQF_TRIGGER_LOW | IRQF_ONESHOT,
				  da9055->irq_base, &da9055_regmap_irq_chip,
				  &da9055->irq_data);
	if (ret < 0)
		return ret;

	da9055->irq_base = regmap_irq_chip_get_base(da9055->irq_data);

	ret = mfd_add_devices(da9055->dev, -1,
			      da9055_devs, ARRAY_SIZE(da9055_devs),
			      NULL, da9055->irq_base, NULL);
	if (ret)
		goto err;

	return 0;

err:
	mfd_remove_devices(da9055->dev);
	return ret;
}
int __devinit da9052_device_init(struct da9052 *da9052, u8 chip_id)
{
    struct da9052_pdata *pdata = da9052->dev->platform_data;
    struct irq_desc *desc;
    int ret;

    if (pdata && pdata->init != NULL)
        pdata->init(da9052);

    da9052->chip_id = chip_id;

    if (!pdata || !pdata->irq_base)
        da9052->irq_base = -1;
    else
        da9052->irq_base = pdata->irq_base;

    ret = regmap_add_irq_chip(da9052->regmap, da9052->chip_irq,
                              IRQF_TRIGGER_LOW | IRQF_ONESHOT,
                              da9052->irq_base, &da9052_regmap_irq_chip,
                              NULL);
    if (ret < 0)
        goto regmap_err;

    desc = irq_to_desc(da9052->chip_irq);
    da9052->irq_base = regmap_irq_chip_get_base(desc->action->dev_id);

    ret = mfd_add_devices(da9052->dev, -1, da9052_subdev_info,
                          ARRAY_SIZE(da9052_subdev_info), NULL, 0);
    if (ret)
        goto err;

    return 0;

err:
    mfd_remove_devices(da9052->dev);
regmap_err:
    return ret;
}
示例#13
0
文件: palmas.c 项目: AllenDou/linux
static int __devinit palmas_i2c_probe(struct i2c_client *i2c,
			    const struct i2c_device_id *id)
{
	struct palmas *palmas;
	struct palmas_platform_data *pdata;
	struct device_node *node = i2c->dev.of_node;
	int ret = 0, i;
	unsigned int reg, addr;
	int slave;
	struct mfd_cell *children;

	pdata = dev_get_platdata(&i2c->dev);

	if (node && !pdata) {
		pdata = devm_kzalloc(&i2c->dev, sizeof(*pdata), GFP_KERNEL);

		if (!pdata)
			return -ENOMEM;

		palmas_dt_to_pdata(node, pdata);
	}

	if (!pdata)
		return -EINVAL;

	palmas = devm_kzalloc(&i2c->dev, sizeof(struct palmas), GFP_KERNEL);
	if (palmas == NULL)
		return -ENOMEM;

	i2c_set_clientdata(i2c, palmas);
	palmas->dev = &i2c->dev;
	palmas->id = id->driver_data;
	palmas->irq = i2c->irq;

	for (i = 0; i < PALMAS_NUM_CLIENTS; i++) {
		if (i == 0)
			palmas->i2c_clients[i] = i2c;
		else {
			palmas->i2c_clients[i] =
					i2c_new_dummy(i2c->adapter,
							i2c->addr + i);
			if (!palmas->i2c_clients[i]) {
				dev_err(palmas->dev,
					"can't attach client %d\n", i);
				ret = -ENOMEM;
				goto err;
			}
		}
		palmas->regmap[i] = devm_regmap_init_i2c(palmas->i2c_clients[i],
				&palmas_regmap_config[i]);
		if (IS_ERR(palmas->regmap[i])) {
			ret = PTR_ERR(palmas->regmap[i]);
			dev_err(palmas->dev,
				"Failed to allocate regmap %d, err: %d\n",
				i, ret);
			goto err;
		}
	}

	/* Change IRQ into clear on read mode for efficiency */
	slave = PALMAS_BASE_TO_SLAVE(PALMAS_INTERRUPT_BASE);
	addr = PALMAS_BASE_TO_REG(PALMAS_INTERRUPT_BASE, PALMAS_INT_CTRL);
	reg = PALMAS_INT_CTRL_INT_CLEAR;

	regmap_write(palmas->regmap[slave], addr, reg);

	ret = regmap_add_irq_chip(palmas->regmap[slave], palmas->irq,
			IRQF_ONESHOT | IRQF_TRIGGER_LOW, 0, &palmas_irq_chip,
			&palmas->irq_data);
	if (ret < 0)
		goto err;

	slave = PALMAS_BASE_TO_SLAVE(PALMAS_PU_PD_OD_BASE);
	addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE,
			PALMAS_PRIMARY_SECONDARY_PAD1);

	if (pdata->mux_from_pdata) {
		reg = pdata->pad1;
		ret = regmap_write(palmas->regmap[slave], addr, reg);
		if (ret)
			goto err_irq;
	} else {
		ret = regmap_read(palmas->regmap[slave], addr, &reg);
		if (ret)
			goto err_irq;
	}

	if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_0))
		palmas->gpio_muxed |= PALMAS_GPIO_0_MUXED;
	if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_MASK))
		palmas->gpio_muxed |= PALMAS_GPIO_1_MUXED;
	else if ((reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_MASK) ==
			(2 << PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_SHIFT))
		palmas->led_muxed |= PALMAS_LED1_MUXED;
	else if ((reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_MASK) ==
			(3 << PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_1_SHIFT))
		palmas->pwm_muxed |= PALMAS_PWM1_MUXED;
	if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_MASK))
		palmas->gpio_muxed |= PALMAS_GPIO_2_MUXED;
	else if ((reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_MASK) ==
			(2 << PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_SHIFT))
		palmas->led_muxed |= PALMAS_LED2_MUXED;
	else if ((reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_MASK) ==
			(3 << PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_2_SHIFT))
		palmas->pwm_muxed |= PALMAS_PWM2_MUXED;
	if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_3))
		palmas->gpio_muxed |= PALMAS_GPIO_3_MUXED;

	addr = PALMAS_BASE_TO_REG(PALMAS_PU_PD_OD_BASE,
			PALMAS_PRIMARY_SECONDARY_PAD2);

	if (pdata->mux_from_pdata) {
		reg = pdata->pad2;
		ret = regmap_write(palmas->regmap[slave], addr, reg);
		if (ret)
			goto err_irq;
	} else {
		ret = regmap_read(palmas->regmap[slave], addr, &reg);
		if (ret)
			goto err_irq;
	}

	if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_4))
		palmas->gpio_muxed |= PALMAS_GPIO_4_MUXED;
	if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_5_MASK))
		palmas->gpio_muxed |= PALMAS_GPIO_5_MUXED;
	if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_6))
		palmas->gpio_muxed |= PALMAS_GPIO_6_MUXED;
	if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_7_MASK))
		palmas->gpio_muxed |= PALMAS_GPIO_7_MUXED;

	dev_info(palmas->dev, "Muxing GPIO %x, PWM %x, LED %x\n",
			palmas->gpio_muxed, palmas->pwm_muxed,
			palmas->led_muxed);

	reg = pdata->power_ctrl;

	slave = PALMAS_BASE_TO_SLAVE(PALMAS_PMU_CONTROL_BASE);
	addr = PALMAS_BASE_TO_REG(PALMAS_PMU_CONTROL_BASE, PALMAS_POWER_CTRL);

	ret = regmap_write(palmas->regmap[slave], addr, reg);
	if (ret)
		goto err_irq;

	/*
	 * If we are probing with DT do this the DT way and return here
	 * otherwise continue and add devices using mfd helpers.
	 */
	if (node) {
		ret = of_platform_populate(node, NULL, NULL, &i2c->dev);
		if (ret < 0)
			goto err_irq;
		else
			return ret;
	}

	children = kmemdup(palmas_children, sizeof(palmas_children),
			   GFP_KERNEL);
	if (!children) {
		ret = -ENOMEM;
		goto err_irq;
	}

	children[PALMAS_PMIC_ID].platform_data = pdata->pmic_pdata;
	children[PALMAS_PMIC_ID].pdata_size = sizeof(*pdata->pmic_pdata);

	children[PALMAS_GPADC_ID].platform_data = pdata->gpadc_pdata;
	children[PALMAS_GPADC_ID].pdata_size = sizeof(*pdata->gpadc_pdata);

	children[PALMAS_RESOURCE_ID].platform_data = pdata->resource_pdata;
	children[PALMAS_RESOURCE_ID].pdata_size =
			sizeof(*pdata->resource_pdata);

	children[PALMAS_USB_ID].platform_data = pdata->usb_pdata;
	children[PALMAS_USB_ID].pdata_size = sizeof(*pdata->usb_pdata);

	children[PALMAS_CLK_ID].platform_data = pdata->clk_pdata;
	children[PALMAS_CLK_ID].pdata_size = sizeof(*pdata->clk_pdata);

	ret = mfd_add_devices(palmas->dev, -1,
			      children, ARRAY_SIZE(palmas_children),
			      NULL, regmap_irq_chip_get_base(palmas->irq_data),
			      NULL);
	kfree(children);

	if (ret < 0)
		goto err_devices;

	return ret;

err_devices:
	mfd_remove_devices(palmas->dev);
err_irq:
	regmap_del_irq_chip(palmas->irq, palmas->irq_data);
err:
	return ret;
}
示例#14
0
static int da9150_probe(struct i2c_client *client,
			const struct i2c_device_id *id)
{
	struct da9150 *da9150;
	struct da9150_pdata *pdata = dev_get_platdata(&client->dev);
	int qif_addr;
	int ret;

	da9150 = devm_kzalloc(&client->dev, sizeof(*da9150), GFP_KERNEL);
	if (!da9150)
		return -ENOMEM;

	da9150->dev = &client->dev;
	da9150->irq = client->irq;
	i2c_set_clientdata(client, da9150);

	da9150->regmap = devm_regmap_init_i2c(client, &da9150_regmap_config);
	if (IS_ERR(da9150->regmap)) {
		ret = PTR_ERR(da9150->regmap);
		dev_err(da9150->dev, "Failed to allocate register map: %d\n",
			ret);
		return ret;
	}

	/* Setup secondary I2C interface for QIF access */
	qif_addr = da9150_reg_read(da9150, DA9150_CORE2WIRE_CTRL_A);
	qif_addr = (qif_addr & DA9150_CORE_BASE_ADDR_MASK) >> 1;
	qif_addr |= DA9150_QIF_I2C_ADDR_LSB;
	da9150->core_qif = i2c_new_dummy(client->adapter, qif_addr);
	if (!da9150->core_qif) {
		dev_err(da9150->dev, "Failed to attach QIF client\n");
		return -ENODEV;
	}

	i2c_set_clientdata(da9150->core_qif, da9150);

	if (pdata) {
		da9150->irq_base = pdata->irq_base;

		da9150_devs[DA9150_FG_IDX].platform_data = pdata->fg_pdata;
		da9150_devs[DA9150_FG_IDX].pdata_size =
			sizeof(struct da9150_fg_pdata);
	} else {
		da9150->irq_base = -1;
	}

	ret = regmap_add_irq_chip(da9150->regmap, da9150->irq,
				  IRQF_TRIGGER_LOW | IRQF_ONESHOT,
				  da9150->irq_base, &da9150_regmap_irq_chip,
				  &da9150->regmap_irq_data);
	if (ret) {
		dev_err(da9150->dev, "Failed to add regmap irq chip: %d\n",
			ret);
		goto regmap_irq_fail;
	}


	da9150->irq_base = regmap_irq_chip_get_base(da9150->regmap_irq_data);

	enable_irq_wake(da9150->irq);

	ret = mfd_add_devices(da9150->dev, -1, da9150_devs,
			      ARRAY_SIZE(da9150_devs), NULL,
			      da9150->irq_base, NULL);
	if (ret) {
		dev_err(da9150->dev, "Failed to add child devices: %d\n", ret);
		goto mfd_fail;
	}

	return 0;

mfd_fail:
	regmap_del_irq_chip(da9150->irq, da9150->regmap_irq_data);
regmap_irq_fail:
	i2c_unregister_device(da9150->core_qif);

	return ret;
}