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; }
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; }
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; }
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; }
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; }
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, ®); 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, ®); 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; }
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; }