static int __devinit pm8018_add_subdevices(const struct pm8018_platform_data *pdata, struct pm8018 *pmic) { int ret = 0, irq_base = 0; struct pm_irq_chip *irq_chip; if (pdata->irq_pdata) { pdata->irq_pdata->irq_cdata.nirqs = PM8018_NR_IRQS; pdata->irq_pdata->irq_cdata.base_addr = REG_IRQ_BASE; irq_base = pdata->irq_pdata->irq_base; irq_chip = pm8xxx_irq_init(pmic->dev, pdata->irq_pdata); if (IS_ERR(irq_chip)) { pr_err("Failed to init interrupts ret=%ld\n", PTR_ERR(irq_chip)); return PTR_ERR(irq_chip); } pmic->irq_chip = irq_chip; } if (pdata->gpio_pdata) { pdata->gpio_pdata->gpio_cdata.ngpios = PM8018_NR_GPIOS; gpio_cell.platform_data = pdata->gpio_pdata; gpio_cell.pdata_size = sizeof(struct pm8xxx_gpio_platform_data); ret = mfd_add_devices(pmic->dev, 0, &gpio_cell, 1, NULL, irq_base); if (ret) { pr_err("Failed to add gpio subdevice ret=%d\n", ret); goto bail; } } if (pdata->mpp_pdata) { pdata->mpp_pdata->core_data.nmpps = PM8018_NR_MPPS; pdata->mpp_pdata->core_data.base_addr = REG_MPP_BASE; mpp_cell.platform_data = pdata->mpp_pdata; mpp_cell.pdata_size = sizeof(struct pm8xxx_mpp_platform_data); ret = mfd_add_devices(pmic->dev, 0, &mpp_cell, 1, NULL, irq_base); if (ret) { pr_err("Failed to add mpp subdevice ret=%d\n", ret); goto bail; } } if (pdata->rtc_pdata) { rtc_cell.platform_data = pdata->rtc_pdata; rtc_cell.pdata_size = sizeof(struct pm8xxx_rtc_platform_data); ret = mfd_add_devices(pmic->dev, 0, &rtc_cell, 1, NULL, irq_base); if (ret) { pr_err("Failed to add rtc subdevice ret=%d\n", ret); goto bail; } } if (pdata->pwrkey_pdata) { pwrkey_cell.platform_data = pdata->pwrkey_pdata; pwrkey_cell.pdata_size = sizeof(struct pm8xxx_pwrkey_platform_data); ret = mfd_add_devices(pmic->dev, 0, &pwrkey_cell, 1, NULL, irq_base); if (ret) { pr_err("Failed to add pwrkey subdevice ret=%d\n", ret); goto bail; } } if (pdata->misc_pdata) { misc_cell.platform_data = pdata->misc_pdata; misc_cell.pdata_size = sizeof(struct pm8xxx_misc_platform_data); ret = mfd_add_devices(pmic->dev, 0, &misc_cell, 1, NULL, irq_base); if (ret) { pr_err("Failed to add misc subdevice ret=%d\n", ret); goto bail; } } if (pdata->adc_pdata) { adc_cell.platform_data = pdata->adc_pdata; adc_cell.pdata_size = sizeof(struct pm8xxx_adc_platform_data); ret = mfd_add_devices(pmic->dev, 0, &adc_cell, 1, NULL, irq_base); if (ret) { pr_err("Failed to add adc subdevice ret=%d\n", ret); } } if (pdata->leds_pdata) { leds_cell.platform_data = pdata->leds_pdata; leds_cell.pdata_size = sizeof(struct pm8xxx_led_platform_data); ret = mfd_add_devices(pmic->dev, 0, &leds_cell, 1, NULL, 0); if (ret) { pr_err("Failed to add leds subdevice ret=%d\n", ret); goto bail; } } ret = mfd_add_devices(pmic->dev, 0, &debugfs_cell, 1, NULL, irq_base); if (ret) { pr_err("Failed to add debugfs subdevice ret=%d\n", ret); goto bail; } ret = mfd_add_devices(pmic->dev, 0, &pwm_cell, 1, NULL, 0); if (ret) { pr_err("Failed to add pwm subdevice ret=%d\n", ret); goto bail; } if (pdata->num_regulators > 0 && pdata->regulator_pdatas) { ret = pm8018_add_regulators(pdata, pmic, irq_base); if (ret) { pr_err("Failed to add regulator subdevices ret=%d\n", ret); goto bail; } } ret = mfd_add_devices(pmic->dev, 0, &thermal_alarm_cell, 1, NULL, irq_base); if (ret) { pr_err("Failed to add thermal alarm subdevice, ret=%d\n", ret); goto bail; } return 0; bail: if (pmic->irq_chip) { pm8xxx_irq_exit(pmic->irq_chip); pmic->irq_chip = NULL; } return ret; }
int __devinit arizona_dev_init(struct arizona *arizona) { struct device *dev = arizona->dev; const char *type_name; unsigned int reg, val; int ret, i; dev_set_drvdata(arizona->dev, arizona); mutex_init(&arizona->clk_lock); if (dev_get_platdata(arizona->dev)) memcpy(&arizona->pdata, dev_get_platdata(arizona->dev), sizeof(arizona->pdata)); regcache_cache_only(arizona->regmap, true); switch (arizona->type) { case WM5102: case WM5110: for (i = 0; i < ARRAY_SIZE(wm5102_core_supplies); i++) arizona->core_supplies[i].supply = wm5102_core_supplies[i]; arizona->num_core_supplies = ARRAY_SIZE(wm5102_core_supplies); break; default: dev_err(arizona->dev, "Unknown device type %d\n", arizona->type); return -EINVAL; } ret = mfd_add_devices(arizona->dev, -1, early_devs, ARRAY_SIZE(early_devs), NULL, 0); if (ret != 0) { dev_err(dev, "Failed to add early children: %d\n", ret); return ret; } ret = regulator_bulk_get(dev, arizona->num_core_supplies, arizona->core_supplies); if (ret != 0) { dev_err(dev, "Failed to request core supplies: %d\n", ret); goto err_early; } ret = regulator_bulk_enable(arizona->num_core_supplies, arizona->core_supplies); if (ret != 0) { dev_err(dev, "Failed to enable core supplies: %d\n", ret); goto err_bulk_get; } if (arizona->pdata.reset) { /* Start out with /RESET low to put the chip into reset */ ret = gpio_request_one(arizona->pdata.reset, GPIOF_DIR_OUT | GPIOF_INIT_LOW, "arizona /RESET"); if (ret != 0) { dev_err(dev, "Failed to request /RESET: %d\n", ret); goto err_enable; } gpio_set_value_cansleep(arizona->pdata.reset, 1); } if (arizona->pdata.ldoena) { ret = gpio_request_one(arizona->pdata.ldoena, GPIOF_DIR_OUT | GPIOF_INIT_HIGH, "arizona LDOENA"); if (ret != 0) { dev_err(dev, "Failed to request LDOENA: %d\n", ret); goto err_reset; } } regcache_cache_only(arizona->regmap, false); ret = regmap_read(arizona->regmap, ARIZONA_SOFTWARE_RESET, ®); if (ret != 0) { dev_err(dev, "Failed to read ID register: %d\n", ret); goto err_ldoena; } ret = regmap_read(arizona->regmap, ARIZONA_DEVICE_REVISION, &arizona->rev); if (ret != 0) { dev_err(dev, "Failed to read revision register: %d\n", ret); goto err_ldoena; } arizona->rev &= ARIZONA_DEVICE_REVISION_MASK; switch (reg) { #ifdef CONFIG_MFD_WM5102 case 0x5102: type_name = "WM5102"; if (arizona->type != WM5102) { dev_err(arizona->dev, "WM5102 registered as %d\n", arizona->type); arizona->type = WM5102; } ret = wm5102_patch(arizona); break; #endif #ifdef CONFIG_MFD_WM5110 case 0x5110: type_name = "WM5110"; if (arizona->type != WM5110) { dev_err(arizona->dev, "WM5110 registered as %d\n", arizona->type); arizona->type = WM5110; } ret = wm5110_patch(arizona); break; #endif default: dev_err(arizona->dev, "Unknown device ID %x\n", reg); goto err_ldoena; } dev_info(dev, "%s revision %c\n", type_name, arizona->rev + 'A'); if (ret != 0) dev_err(arizona->dev, "Failed to apply patch: %d\n", ret); /* If we have a /RESET GPIO we'll already be reset */ if (!arizona->pdata.reset) { ret = regmap_write(arizona->regmap, ARIZONA_SOFTWARE_RESET, 0); if (ret != 0) { dev_err(dev, "Failed to reset device: %d\n", ret); goto err_ldoena; } } ret = arizona_wait_for_boot(arizona); if (ret != 0) { dev_err(arizona->dev, "Device failed initial boot: %d\n", ret); goto err_reset; } for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) { if (!arizona->pdata.gpio_defaults[i]) continue; regmap_write(arizona->regmap, ARIZONA_GPIO1_CTRL + i, arizona->pdata.gpio_defaults[i]); } pm_runtime_set_autosuspend_delay(arizona->dev, 100); pm_runtime_use_autosuspend(arizona->dev); pm_runtime_enable(arizona->dev); /* Chip default */ if (!arizona->pdata.clk32k_src) arizona->pdata.clk32k_src = ARIZONA_32KZ_MCLK2; switch (arizona->pdata.clk32k_src) { case ARIZONA_32KZ_MCLK1: case ARIZONA_32KZ_MCLK2: regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1, ARIZONA_CLK_32K_SRC_MASK, arizona->pdata.clk32k_src - 1); break; case ARIZONA_32KZ_NONE: regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1, ARIZONA_CLK_32K_SRC_MASK, 2); break; default: dev_err(arizona->dev, "Invalid 32kHz clock source: %d\n", arizona->pdata.clk32k_src); ret = -EINVAL; goto err_ldoena; } for (i = 0; i < ARIZONA_MAX_INPUT; i++) { /* Default for both is 0 so noop with defaults */ val = arizona->pdata.dmic_ref[i] << ARIZONA_IN1_DMIC_SUP_SHIFT; val |= arizona->pdata.inmode[i] << ARIZONA_IN1_MODE_SHIFT; regmap_update_bits(arizona->regmap, ARIZONA_IN1L_CONTROL + (i * 8), ARIZONA_IN1_DMIC_SUP_MASK | ARIZONA_IN1_MODE_MASK, val); } for (i = 0; i < ARIZONA_MAX_OUTPUT; i++) { /* Default is 0 so noop with defaults */ if (arizona->pdata.out_mono[i]) val = ARIZONA_OUT1_MONO; else val = 0; regmap_update_bits(arizona->regmap, ARIZONA_OUTPUT_PATH_CONFIG_1L + (i * 8), ARIZONA_OUT1_MONO, val); } for (i = 0; i < ARIZONA_MAX_PDM_SPK; i++) { if (arizona->pdata.spk_mute[i]) regmap_update_bits(arizona->regmap, ARIZONA_PDM_SPK1_CTRL_1 + (i * 2), ARIZONA_SPK1_MUTE_ENDIAN_MASK | ARIZONA_SPK1_MUTE_SEQ1_MASK, arizona->pdata.spk_mute[i]); if (arizona->pdata.spk_fmt[i]) regmap_update_bits(arizona->regmap, ARIZONA_PDM_SPK1_CTRL_2 + (i * 2), ARIZONA_SPK1_FMT_MASK, arizona->pdata.spk_fmt[i]); } /* Set up for interrupts */ ret = arizona_irq_init(arizona); if (ret != 0) goto err_ldoena; arizona_request_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, "CLKGEN error", arizona_clkgen_err, arizona); arizona_request_irq(arizona, ARIZONA_IRQ_OVERCLOCKED, "Overclocked", arizona_overclocked, arizona); arizona_request_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, "Underclocked", arizona_underclocked, arizona); switch (arizona->type) { case WM5102: ret = mfd_add_devices(arizona->dev, -1, wm5102_devs, ARRAY_SIZE(wm5102_devs), NULL, 0); break; case WM5110: ret = mfd_add_devices(arizona->dev, -1, wm5110_devs, ARRAY_SIZE(wm5110_devs), NULL, 0); break; } if (ret != 0) { dev_err(arizona->dev, "Failed to add subdevices: %d\n", ret); goto err_irq; } return 0; err_irq: arizona_irq_exit(arizona); err_ldoena: if (arizona->pdata.ldoena) { gpio_set_value_cansleep(arizona->pdata.ldoena, 0); gpio_free(arizona->pdata.ldoena); } err_reset: if (arizona->pdata.reset) { gpio_set_value_cansleep(arizona->pdata.reset, 1); gpio_free(arizona->pdata.reset); } err_enable: regulator_bulk_disable(ARRAY_SIZE(arizona->core_supplies), arizona->core_supplies); err_bulk_get: regulator_bulk_free(ARRAY_SIZE(arizona->core_supplies), arizona->core_supplies); err_early: mfd_remove_devices(dev); return ret; }
static int __devinit twl4030_codec_probe(struct platform_device *pdev) { struct twl4030_codec *codec; struct twl4030_codec_data *pdata = pdev->dev.platform_data; struct mfd_cell *cell = NULL; int ret, childs = 0; u8 val; if (!pdata) { dev_err(&pdev->dev, "Platform data is missing\n"); return -EINVAL; } /* Configure APLL_INFREQ and disable APLL if enabled */ val = 0; switch (pdata->audio_mclk) { case 19200000: val |= TWL4030_APLL_INFREQ_19200KHZ; break; case 26000000: val |= TWL4030_APLL_INFREQ_26000KHZ; break; case 38400000: val |= TWL4030_APLL_INFREQ_38400KHZ; break; default: dev_err(&pdev->dev, "Invalid audio_mclk\n"); return -EINVAL; } twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, val, TWL4030_REG_APLL_CTL); codec = kzalloc(sizeof(struct twl4030_codec), GFP_KERNEL); if (!codec) return -ENOMEM; platform_set_drvdata(pdev, codec); printk("twl4030_codec_probe: (%d)\n", pdata->audpwron_gpio); twl4030_codec_dev = pdev; mutex_init(&codec->mutex); codec->audio_mclk = pdata->audio_mclk; //codec->dev->audpwron_gpio = pdata->audpwron_gpio; /* Codec power */ codec->resource[TWL4030_CODEC_RES_POWER].reg = TWL4030_REG_CODEC_MODE; codec->resource[TWL4030_CODEC_RES_POWER].mask = TWL4030_CODECPDZ; /* PLL */ codec->resource[TWL4030_CODEC_RES_APLL].reg = TWL4030_REG_APLL_CTL; codec->resource[TWL4030_CODEC_RES_APLL].mask = TWL4030_APLL_EN; if (pdata->audio) { cell = &codec->cells[childs]; cell->name = "twl4030-codec"; cell->platform_data = pdata->audio; cell->data_size = sizeof(*pdata->audio); childs++; } if (pdata->vibra) { cell = &codec->cells[childs]; cell->name = "twl4030-vibra"; cell->platform_data = pdata->vibra; cell->data_size = sizeof(*pdata->vibra); childs++; } if (childs) ret = mfd_add_devices(&pdev->dev, pdev->id, codec->cells, childs, NULL, 0); else { dev_err(&pdev->dev, "No platform data found for childs\n"); ret = -ENODEV; } if (!ret) return 0; platform_set_drvdata(pdev, NULL); kfree(codec); twl4030_codec_dev = NULL; return ret; }
static int max8997_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct max8997_dev *max8997; struct max8997_platform_data *pdata = dev_get_platdata(&i2c->dev); int ret = 0; max8997 = devm_kzalloc(&i2c->dev, sizeof(struct max8997_dev), GFP_KERNEL); if (max8997 == NULL) return -ENOMEM; i2c_set_clientdata(i2c, max8997); max8997->dev = &i2c->dev; max8997->i2c = i2c; max8997->type = max8997_i2c_get_driver_data(i2c, id); max8997->irq = i2c->irq; if (IS_ENABLED(CONFIG_OF) && max8997->dev->of_node) { pdata = max8997_i2c_parse_dt_pdata(max8997->dev); if (IS_ERR(pdata)) return PTR_ERR(pdata); } if (!pdata) return ret; max8997->pdata = pdata; max8997->ono = pdata->ono; mutex_init(&max8997->iolock); max8997->rtc = i2c_new_dummy(i2c->adapter, I2C_ADDR_RTC); i2c_set_clientdata(max8997->rtc, max8997); max8997->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC); i2c_set_clientdata(max8997->haptic, max8997); max8997->muic = i2c_new_dummy(i2c->adapter, I2C_ADDR_MUIC); i2c_set_clientdata(max8997->muic, max8997); pm_runtime_set_active(max8997->dev); max8997_irq_init(max8997); ret = mfd_add_devices(max8997->dev, -1, max8997_devs, ARRAY_SIZE(max8997_devs), NULL, 0, NULL); if (ret < 0) { dev_err(max8997->dev, "failed to add MFD devices %d\n", ret); goto err_mfd; } /* * TODO: enable others (flash, muic, rtc, battery, ...) and * check the return value */ /* MAX8997 has a power button input. */ device_init_wakeup(max8997->dev, pdata->wakeup); return ret; err_mfd: mfd_remove_devices(max8997->dev); i2c_unregister_device(max8997->muic); i2c_unregister_device(max8997->haptic); i2c_unregister_device(max8997->rtc); return ret; }
static int __devinit pm8921_add_regulators(const struct pm8921_platform_data *pdata, struct pm8921 *pmic, int irq_base) { int ret = 0; struct mfd_cell *mfd_regulators; struct pm8xxx_regulator_core_platform_data *cdata; enum pm8xxx_version version; int i; version = pm8xxx_get_version(pmic->dev); /* Add one device for each regulator used by the board. */ mfd_regulators = kzalloc(sizeof(struct mfd_cell) * (pdata->num_regulators), GFP_KERNEL); if (!mfd_regulators) { pr_err("Cannot allocate %d bytes for pm8921 regulator " "mfd cells\n", sizeof(struct mfd_cell) * (pdata->num_regulators)); return -ENOMEM; } cdata = kzalloc(sizeof(struct pm8xxx_regulator_core_platform_data) * pdata->num_regulators, GFP_KERNEL); if (!cdata) { pr_err("Cannot allocate %d bytes for pm8921 regulator " "core data\n", pdata->num_regulators * sizeof(struct pm8xxx_regulator_core_platform_data)); kfree(mfd_regulators); return -ENOMEM; } for (i = 0; i < ARRAY_SIZE(regulator_data); i++) mutex_init(®ulator_data[i].pc_lock); for (i = 0; i < ARRAY_SIZE(pm8917_regulator_data); i++) mutex_init(&pm8917_regulator_data[i].pc_lock); for (i = 0; i < pdata->num_regulators; i++) { if (!pdata->regulator_pdatas[i].init_data.constraints.name) { pr_err("name missing for regulator %d\n", i); ret = -EINVAL; goto bail; } if (!match_regulator(version, &cdata[i], pdata->regulator_pdatas[i].init_data.constraints.name)) { ret = -ENODEV; goto bail; } cdata[i].pdata = &(pdata->regulator_pdatas[i]); mfd_regulators[i].name = PM8XXX_REGULATOR_DEV_NAME; mfd_regulators[i].id = cdata[i].pdata->id; mfd_regulators[i].platform_data = &cdata[i]; mfd_regulators[i].pdata_size = sizeof(struct pm8xxx_regulator_core_platform_data); } ret = mfd_add_devices(pmic->dev, 0, mfd_regulators, pdata->num_regulators, NULL, irq_base); if (ret) goto bail; pmic->mfd_regulators = mfd_regulators; pmic->regulator_cdata = cdata; return ret; bail: for (i = 0; i < ARRAY_SIZE(regulator_data); i++) mutex_destroy(®ulator_data[i].pc_lock); for (i = 0; i < ARRAY_SIZE(pm8917_regulator_data); i++) mutex_destroy(&pm8917_regulator_data[i].pc_lock); kfree(mfd_regulators); kfree(cdata); return ret; }
static int vprbrd_probe(struct usb_interface *interface, const struct usb_device_id *id) { struct vprbrd *vb; u16 version = 0; int pipe, ret; /* allocate memory for our device state and initialize it */ vb = kzalloc(sizeof(*vb), GFP_KERNEL); if (vb == NULL) { dev_err(&interface->dev, "Out of memory\n"); return -ENOMEM; } mutex_init(&vb->lock); vb->usb_dev = usb_get_dev(interface_to_usbdev(interface)); /* save our data pointer in this interface device */ usb_set_intfdata(interface, vb); dev_set_drvdata(&vb->pdev.dev, vb); /* get version information, major first, minor then */ pipe = usb_rcvctrlpipe(vb->usb_dev, 0); ret = usb_control_msg(vb->usb_dev, pipe, VPRBRD_USB_REQUEST_MAJOR, VPRBRD_USB_TYPE_IN, 0x0000, 0x0000, vb->buf, 1, VPRBRD_USB_TIMEOUT_MS); if (ret == 1) version = vb->buf[0]; ret = usb_control_msg(vb->usb_dev, pipe, VPRBRD_USB_REQUEST_MINOR, VPRBRD_USB_TYPE_IN, 0x0000, 0x0000, vb->buf, 1, VPRBRD_USB_TIMEOUT_MS); if (ret == 1) { version <<= 8; version = version | vb->buf[0]; } dev_info(&interface->dev, "version %x.%02x found at bus %03d address %03d\n", version >> 8, version & 0xff, vb->usb_dev->bus->busnum, vb->usb_dev->devnum); ret = mfd_add_devices(&interface->dev, PLATFORM_DEVID_AUTO, vprbrd_devs, ARRAY_SIZE(vprbrd_devs), NULL, 0, NULL); if (ret != 0) { dev_err(&interface->dev, "Failed to add mfd devices to core."); goto error; } return 0; error: if (vb) { usb_put_dev(vb->usb_dev); kfree(vb); } return ret; }
static int pm8901_probe(struct i2c_client *client, const struct i2c_device_id *id) { int i, rc; struct pm8901_platform_data *pdata = client->dev.platform_data; struct pm8901_chip *chip; if (pdata == NULL || !client->irq) { pr_err("%s: No platform_data or IRQ.\n", __func__); return -ENODEV; } if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) { pr_err("%s: i2c_check_functionality failed.\n", __func__); return -ENODEV; } chip = kzalloc(sizeof *chip, GFP_KERNEL); if (chip == NULL) { pr_err("%s: kzalloc() failed.\n", __func__); return -ENOMEM; } chip->dev = client; /* Read PMIC chip revision */ rc = ssbi_read(chip->dev, SSBI_REG_REV, &chip->revision, 1); if (rc) pr_err("%s: Failed on ssbi_read for revision: rc=%d.\n", __func__, rc); pr_info("%s: PMIC revision: %X\n", __func__, chip->revision); (void) memcpy((void *)&chip->pdata, (const void *)pdata, sizeof(chip->pdata)); set_irq_data(chip->dev->irq, (void *)chip); set_irq_wake(chip->dev->irq, 1); chip->pm_max_irq = 0; chip->pm_max_blocks = 0; chip->pm_max_masters = 0; i2c_set_clientdata(client, chip); pmic_chip = chip; spin_lock_init(&chip->pm_lock); /* Register for all reserved IRQs */ for (i = pdata->irq_base; i < (pdata->irq_base + MAX_PM_IRQ); i++) { set_irq_chip(i, &pm8901_irq_chip); set_irq_handler(i, handle_edge_irq); set_irq_flags(i, IRQF_VALID); set_irq_data(i, (void *)chip); } /* Add sub devices with the chip parameter as driver data */ for (i = 0; i < pdata->num_subdevs; i++) pdata->sub_devices[i].driver_data = chip; rc = mfd_add_devices(&chip->dev->dev, 0, pdata->sub_devices, pdata->num_subdevs, NULL, 0); if (rc) { pr_err("%s: could not add devices %d\n", __func__, rc); return rc; } rc = request_threaded_irq(chip->dev->irq, NULL, pm8901_isr_thread, IRQF_ONESHOT | IRQF_DISABLED | pdata->irq_trigger_flags, "pm8901-irq", chip); if (rc) pr_err("%s: could not request irq %d: %d\n", __func__, chip->dev->irq, rc); rc = pmic8901_dbg_probe(chip); if (rc < 0) pr_err("%s: could not set up debugfs: %d\n", __func__, rc); return rc; }
static int __init davinci_vc_probe(struct platform_device *pdev) { struct davinci_vc *davinci_vc; struct resource *res, *mem; struct mfd_cell *cell = NULL; int ret; davinci_vc = kzalloc(sizeof(struct davinci_vc), GFP_KERNEL); if (!davinci_vc) { dev_dbg(&pdev->dev, "could not allocate memory for private data\n"); return -ENOMEM; } davinci_vc->clk = clk_get(&pdev->dev, NULL); if (IS_ERR(davinci_vc->clk)) { dev_dbg(&pdev->dev, "could not get the clock for voice codec\n"); ret = -ENODEV; goto fail1; } clk_enable(davinci_vc->clk); res = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!res) { dev_err(&pdev->dev, "no mem resource\n"); ret = -ENODEV; goto fail2; } davinci_vc->pbase = res->start; davinci_vc->base_size = resource_size(res); mem = request_mem_region(davinci_vc->pbase, davinci_vc->base_size, pdev->name); if (!mem) { dev_err(&pdev->dev, "VCIF region already claimed\n"); ret = -EBUSY; goto fail2; } davinci_vc->base = ioremap(davinci_vc->pbase, davinci_vc->base_size); if (!davinci_vc->base) { dev_err(&pdev->dev, "can't ioremap mem resource.\n"); ret = -ENOMEM; goto fail3; } res = platform_get_resource(pdev, IORESOURCE_DMA, 0); if (!res) { dev_err(&pdev->dev, "no DMA resource\n"); ret = -ENXIO; goto fail4; } davinci_vc->davinci_vcif.dma_tx_channel = res->start; davinci_vc->davinci_vcif.dma_tx_addr = (dma_addr_t)(io_v2p(davinci_vc->base) + DAVINCI_VC_WFIFO); res = platform_get_resource(pdev, IORESOURCE_DMA, 1); if (!res) { dev_err(&pdev->dev, "no DMA resource\n"); ret = -ENXIO; goto fail4; } davinci_vc->davinci_vcif.dma_rx_channel = res->start; davinci_vc->davinci_vcif.dma_rx_addr = (dma_addr_t)(io_v2p(davinci_vc->base) + DAVINCI_VC_RFIFO); davinci_vc->dev = &pdev->dev; davinci_vc->pdev = pdev; /* Voice codec interface client */ cell = &davinci_vc->cells[DAVINCI_VC_VCIF_CELL]; cell->name = "davinci-vcif"; cell->mfd_data = davinci_vc; /* Voice codec CQ93VC client */ cell = &davinci_vc->cells[DAVINCI_VC_CQ93VC_CELL]; cell->name = "cq93vc-codec"; cell->mfd_data = davinci_vc; ret = mfd_add_devices(&pdev->dev, pdev->id, davinci_vc->cells, DAVINCI_VC_CELLS, NULL, 0); if (ret != 0) { dev_err(&pdev->dev, "fail to register client devices\n"); goto fail4; } return 0; fail4: iounmap(davinci_vc->base); fail3: release_mem_region(davinci_vc->pbase, davinci_vc->base_size); fail2: clk_disable(davinci_vc->clk); clk_put(davinci_vc->clk); davinci_vc->clk = NULL; fail1: kfree(davinci_vc); return ret; }
static int __devinit pm8038_add_subdevices(const struct pm8038_platform_data *pdata, struct pm8038 *pmic) { int ret = 0, irq_base = 0; struct pm_irq_chip *irq_chip; if (pdata->irq_pdata) { pdata->irq_pdata->irq_cdata.nirqs = PM8038_NR_IRQS; pdata->irq_pdata->irq_cdata.base_addr = REG_IRQ_BASE; irq_base = pdata->irq_pdata->irq_base; irq_chip = pm8xxx_irq_init(pmic->dev, pdata->irq_pdata); if (IS_ERR(irq_chip)) { pr_err("Failed to init interrupts ret=%ld\n", PTR_ERR(irq_chip)); return PTR_ERR(irq_chip); } pmic->irq_chip = irq_chip; } if (pdata->gpio_pdata) { pdata->gpio_pdata->gpio_cdata.ngpios = PM8038_NR_GPIOS; gpio_cell.platform_data = pdata->gpio_pdata; gpio_cell.pdata_size = sizeof(struct pm8xxx_gpio_platform_data); ret = mfd_add_devices(pmic->dev, 0, &gpio_cell, 1, NULL, irq_base); if (ret) { pr_err("Failed to add gpio subdevice ret=%d\n", ret); goto bail; } } if (pdata->mpp_pdata) { pdata->mpp_pdata->core_data.nmpps = PM8038_NR_MPPS; pdata->mpp_pdata->core_data.base_addr = REG_MPP_BASE; mpp_cell.platform_data = pdata->mpp_pdata; mpp_cell.pdata_size = sizeof(struct pm8xxx_mpp_platform_data); ret = mfd_add_devices(pmic->dev, 0, &mpp_cell, 1, NULL, irq_base); if (ret) { pr_err("Failed to add mpp subdevice ret=%d\n", ret); goto bail; } } if (pdata->rtc_pdata) { rtc_cell.platform_data = pdata->rtc_pdata; rtc_cell.pdata_size = sizeof(struct pm8xxx_rtc_platform_data); ret = mfd_add_devices(pmic->dev, 0, &rtc_cell, 1, NULL, irq_base); if (ret) { pr_err("Failed to add rtc subdevice ret=%d\n", ret); goto bail; } } if (pdata->pwrkey_pdata) { pwrkey_cell.platform_data = pdata->pwrkey_pdata; pwrkey_cell.pdata_size = sizeof(struct pm8xxx_pwrkey_platform_data); ret = mfd_add_devices(pmic->dev, 0, &pwrkey_cell, 1, NULL, irq_base); if (ret) { pr_err("Failed to add pwrkey subdevice ret=%d\n", ret); goto bail; } } ret = mfd_add_devices(pmic->dev, 0, &pwm_cell, 1, NULL, 0); if (ret) { pr_err("Failed to add pwm subdevice ret=%d\n", ret); goto bail; } if (pdata->misc_pdata) { misc_cell.platform_data = pdata->misc_pdata; misc_cell.pdata_size = sizeof(struct pm8xxx_misc_platform_data); ret = mfd_add_devices(pmic->dev, 0, &misc_cell, 1, NULL, irq_base); if (ret) { pr_err("Failed to add misc subdevice ret=%d\n", ret); goto bail; } } if (pdata->leds_pdata) { leds_cell.platform_data = pdata->leds_pdata; leds_cell.pdata_size = sizeof(struct pm8xxx_led_platform_data); ret = mfd_add_devices(pmic->dev, 0, &leds_cell, 1, NULL, 0); if (ret) { pr_err("Failed to add leds subdevice ret=%d\n", ret); goto bail; } } #ifdef CONFIG_PMIC8XXX_VIBRATOR if (pdata->vibrator_pdata) { vibrator_cell.platform_data = pdata->vibrator_pdata; vibrator_cell.pdata_size = sizeof(struct pm8xxx_vibrator_platform_data); ret = mfd_add_devices(pmic->dev, 0, &vibrator_cell, 1, NULL, 0); if (ret) { pr_err("Failed to add vibrator ret=%d\n", ret); goto bail; } } #endif // LGE_CHANGE_S [[email protected]] 2013-02-25, add immersion solution #if defined(CONFIG_TSPDRV) && !defined(CONFIG_MACH_LGE_L9II_COMMON) ret = mfd_add_devices(pmic->dev, 0, &vibrator_cell, 1, NULL, 0); if (ret) { pr_err("Failed to add vibrator ret=%d\n", ret); goto bail; } #endif // LGE_CHANGE_E [[email protected]] 2013-02-25 if (pdata->spk_pdata) { spk_cell.platform_data = pdata->spk_pdata; spk_cell.pdata_size = sizeof(struct pm8xxx_spk_platform_data); ret = mfd_add_devices(pmic->dev, 0, &spk_cell, 1, NULL, 0); if (ret) { pr_err("Failed to add spk subdevice ret=%d\n", ret); goto bail; } } if (pdata->num_regulators > 0 && pdata->regulator_pdatas) { ret = pm8038_add_regulators(pdata, pmic, irq_base); if (ret) { pr_err("Failed to add regulator subdevices ret=%d\n", ret); goto bail; } } ret = mfd_add_devices(pmic->dev, 0, &debugfs_cell, 1, NULL, irq_base); if (ret) { pr_err("Failed to add debugfs subdevice ret=%d\n", ret); goto bail; } if (pdata->adc_pdata) { adc_cell.platform_data = pdata->adc_pdata; adc_cell.pdata_size = sizeof(struct pm8xxx_adc_platform_data); ret = mfd_add_devices(pmic->dev, 0, &adc_cell, 1, NULL, irq_base); if (ret) { pr_err("Failed to add adc subdevices ret=%d\n", ret); } } if (pdata->charger_pdata) { pdata->charger_pdata->charger_cdata.vbat_channel = CHANNEL_VBAT; pdata->charger_pdata->charger_cdata.batt_temp_channel = CHANNEL_BATT_THERM; pdata->charger_pdata->charger_cdata.batt_id_channel = CHANNEL_BATT_ID; charger_cell.platform_data = pdata->charger_pdata; charger_cell.pdata_size = sizeof(struct pm8921_charger_platform_data); ret = mfd_add_devices(pmic->dev, 0, &charger_cell, 1, NULL, irq_base); if (ret) { pr_err("Failed to add charger subdevice ret=%d\n", ret); goto bail; } } if (pdata->bms_pdata) { pdata->bms_pdata->bms_cdata.batt_temp_channel = CHANNEL_BATT_THERM; pdata->bms_pdata->bms_cdata.vbat_channel = CHANNEL_VBAT; pdata->bms_pdata->bms_cdata.ref625mv_channel = CHANNEL_625MV; pdata->bms_pdata->bms_cdata.ref1p25v_channel = CHANNEL_125V; pdata->bms_pdata->bms_cdata.batt_id_channel = CHANNEL_BATT_ID; bms_cell.platform_data = pdata->bms_pdata; bms_cell.pdata_size = sizeof(struct pm8921_bms_platform_data); ret = mfd_add_devices(pmic->dev, 0, &bms_cell, 1, NULL, irq_base); if (ret) { pr_err("Failed to add bms subdevice ret=%d\n", ret); goto bail; } } ret = mfd_add_devices(pmic->dev, 0, &thermal_alarm_cell, 1, NULL, irq_base); if (ret) { pr_err("Failed to add thermal alarm subdevice ret=%d\n", ret); goto bail; } ret = mfd_add_devices(pmic->dev, 0, &batt_alarm_cell, 1, NULL, irq_base); if (ret) { pr_err("Failed to add battery alarm subdevice ret=%d\n", ret); goto bail; } if (pdata->ccadc_pdata) { pdata->ccadc_pdata->ccadc_cdata.batt_temp_channel = CHANNEL_BATT_THERM; ccadc_cell.platform_data = pdata->ccadc_pdata; ccadc_cell.pdata_size = sizeof(struct pm8xxx_ccadc_platform_data); ret = mfd_add_devices(pmic->dev, 0, &ccadc_cell, 1, NULL, irq_base); if (ret) { pr_err("Failed to add ccadc subdevice ret=%d\n", ret); goto bail; } } /* LGE_CHANGE: remove below codes due to QCT patch */ #if 0 // CONFIG_PMIC8XXX_VIBRATOR if (pdata->vibrator_pdata) { vibrator_cell.platform_data = pdata->vibrator_pdata; vibrator_cell.pdata_size = sizeof(struct pm8xxx_vibrator_platform_data); ret = mfd_add_devices(pmic->dev, 0, &vibrator_cell, 1, NULL, 0); if (ret) { pr_err("Failed to add vibrator ret=%d\n", ret); goto bail; } } #endif #ifdef CONFIG_LGE_DIRECT_QCOIN_VIBRATOR if (pdata->pm8xxx_qcoin_pdata) { vibrator_cell.platform_data = pdata->pm8xxx_qcoin_pdata; vibrator_cell.pdata_size = sizeof(struct direct_qcoin_platform_data); ret = mfd_add_devices(pmic->dev, 0, &vibrator_cell, 1, NULL, 0); if (ret) { pr_err("Failed to add vibrator subdevice ret=%d\n",ret); goto bail; } } #endif return 0; bail: if (pmic->irq_chip) { pm8xxx_irq_exit(pmic->irq_chip); pmic->irq_chip = NULL; } return ret; }
static int max14577_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct max14577_dev *max14577; struct max14577_platform_data *pdata = NULL; u8 reg_data; int ret = 0; max14577 = kzalloc(sizeof(struct max14577_dev), GFP_KERNEL); if (max14577 == NULL) return -ENOMEM; if (i2c->dev.of_node) { pdata = devm_kzalloc(&i2c->dev, sizeof(struct max14577_platform_data), GFP_KERNEL); if (!pdata) { dev_err(&i2c->dev, "Failed to allocate memory\n"); ret = -ENOMEM; goto err; } ret = of_max14577_dt(&i2c->dev, pdata); if (ret < 0) { dev_err(&i2c->dev, "Failed to get device of_node\n"); kfree(pdata); goto err; } /*pdata update to other modules*/ i2c->dev.platform_data = pdata; } else pdata = i2c->dev.platform_data; i2c_set_clientdata(i2c, max14577); max14577->dev = &i2c->dev; max14577->i2c = i2c; max14577->irq = i2c->irq; if (pdata) { max14577->pdata = pdata; } else { ret = -EIO; goto err; } pdata->set_cdetctrl1_reg = max14577_set_cdetctrl1_reg; pdata->get_cdetctrl1_reg = max14577_get_cdetctrl1_reg; pdata->set_control2_reg = max14577_set_control2_reg; pdata->get_control2_reg = max14577_get_control2_reg; #ifdef CONFIG_REGULATOR_MAX77836 pdata->regulators = max77836_reglator_pdata; pdata->num_regulators = MAX77836_LDO_MAX; #endif #ifdef CONFIG_CHARGER_MAX14577 pdata->charger_data = &sec_battery_pdata; #endif mutex_init(&max14577->i2c_lock); ret = max14577_read_reg(i2c, MAX14577_REG_DEVICEID, ®_data); if (ret < 0) { pr_err("%s:%s device not found on this channel(%d)\n", MFD_DEV_NAME, __func__, ret); goto err; } else { /* print Device Id */ max14577->vendor_id = (reg_data & 0x7); max14577->device_id = ((reg_data & 0xF8) >> 0x3); pr_info("%s:%s device found: vendor=0x%x, device_id=0x%x\n", MFD_DEV_NAME, __func__, max14577->vendor_id, max14577->device_id); } max14577->i2c_pmic = i2c_new_dummy(i2c->adapter, MAX77836_PMIC_ADDR); i2c_set_clientdata(max14577->i2c_pmic, max14577); ret = max14577_irq_init(max14577); if (ret < 0) goto err_irq_init; ret = mfd_add_devices(max14577->dev, -1, max14577_devs, ARRAY_SIZE(max14577_devs), NULL, 0); if (ret < 0) goto err_mfd; device_init_wakeup(max14577->dev, pdata->wakeup); return ret; err_mfd: mfd_remove_devices(max14577->dev); err_irq_init: if (max14577->i2c_pmic) i2c_unregister_device(max14577->i2c_pmic); err: kfree(max14577); return ret; }
static int __devinit pm8901_add_subdevices(const struct pm8901_platform_data *pdata, struct pm8901_chip *pmic) { int rc = 0, irq_base = 0, i; struct pm_irq_chip *irq_chip; static struct mfd_cell *mfd_regulators; if (pdata->irq_pdata) { pdata->irq_pdata->irq_cdata.nirqs = PM8901_NR_IRQS; pdata->irq_pdata->irq_cdata.base_addr = REG_IRQ_BASE; irq_base = pdata->irq_pdata->irq_base; irq_chip = pm8xxx_irq_init(pmic->dev, pdata->irq_pdata); if (IS_ERR(irq_chip)) { pr_err("Failed to init interrupts ret=%ld\n", PTR_ERR(irq_chip)); return PTR_ERR(irq_chip); } pmic->irq_chip = irq_chip; } if (pdata->mpp_pdata) { pdata->mpp_pdata->core_data.nmpps = PM8901_MPPS; pdata->mpp_pdata->core_data.base_addr = REG_MPP_BASE; mpp_cell.platform_data = pdata->mpp_pdata; mpp_cell.pdata_size = sizeof(struct pm8xxx_mpp_platform_data); rc = mfd_add_devices(pmic->dev, 0, &mpp_cell, 1, NULL, irq_base); if (rc) { pr_err("Failed to add mpp subdevice ret=%d\n", rc); goto bail; } } if (pdata->num_regulators > 0 && pdata->regulator_pdatas) { mfd_regulators = kzalloc(sizeof(struct mfd_cell) * (pdata->num_regulators), GFP_KERNEL); if (!mfd_regulators) { pr_err("Cannot allocate %d bytes for pm8901 regulator " "mfd cells\n", sizeof(struct mfd_cell) * (pdata->num_regulators)); rc = -ENOMEM; goto bail; } for (i = 0; i < pdata->num_regulators; i++) { mfd_regulators[i].name = "pm8901-regulator"; mfd_regulators[i].id = pdata->regulator_pdatas[i].id; mfd_regulators[i].platform_data = &(pdata->regulator_pdatas[i]); mfd_regulators[i].pdata_size = sizeof(struct pm8901_vreg_pdata); } rc = mfd_add_devices(pmic->dev, 0, mfd_regulators, pdata->num_regulators, NULL, irq_base); if (rc) { pr_err("Failed to add regulator subdevices ret=%d\n", rc); kfree(mfd_regulators); goto bail; } pmic->mfd_regulators = mfd_regulators; } rc = mfd_add_devices(pmic->dev, 0, &thermal_alarm_cell, 1, NULL, irq_base); if (rc) { pr_err("Failed to add thermal alarm subdevice ret=%d\n", rc); goto bail; } rc = mfd_add_devices(pmic->dev, 0, &debugfs_cell, 1, NULL, irq_base); if (rc) { pr_err("Failed to add debugfs subdevice ret=%d\n", rc); goto bail; } if (pdata->misc_pdata) { misc_cell.platform_data = pdata->misc_pdata; misc_cell.pdata_size = sizeof(struct pm8xxx_misc_platform_data); rc = mfd_add_devices(pmic->dev, 0, &misc_cell, 1, NULL, irq_base); if (rc) { pr_err("Failed to add misc subdevice ret=%d\n", rc); goto bail; } } return rc; bail: if (pmic->irq_chip) { pm8xxx_irq_exit(pmic->irq_chip); pmic->irq_chip = NULL; } return rc; }
static int max8998_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct max8998_platform_data *pdata = dev_get_platdata(&i2c->dev); struct max8998_dev *max8998; int ret = 0; max8998 = devm_kzalloc(&i2c->dev, sizeof(struct max8998_dev), GFP_KERNEL); if (max8998 == NULL) return -ENOMEM; if (IS_ENABLED(CONFIG_OF) && i2c->dev.of_node) { pdata = max8998_i2c_parse_dt_pdata(&i2c->dev); if (IS_ERR(pdata)) { ret = PTR_ERR(pdata); goto err; } } i2c_set_clientdata(i2c, max8998); max8998->dev = &i2c->dev; max8998->i2c = i2c; max8998->irq = i2c->irq; max8998->type = max8998_i2c_get_driver_data(i2c, id); max8998->pdata = pdata; if (pdata) { max8998->ono = pdata->ono; max8998->irq_base = pdata->irq_base; max8998->wakeup = pdata->wakeup; } mutex_init(&max8998->iolock); max8998->rtc = i2c_new_dummy(i2c->adapter, RTC_I2C_ADDR); if (!max8998->rtc) { dev_err(&i2c->dev, "Failed to allocate I2C device for RTC\n"); return -ENODEV; } i2c_set_clientdata(max8998->rtc, max8998); max8998_irq_init(max8998); pm_runtime_set_active(max8998->dev); switch (max8998->type) { case TYPE_LP3974: ret = mfd_add_devices(max8998->dev, -1, lp3974_devs, ARRAY_SIZE(lp3974_devs), NULL, 0, NULL); break; case TYPE_MAX8998: ret = mfd_add_devices(max8998->dev, -1, max8998_devs, ARRAY_SIZE(max8998_devs), NULL, 0, NULL); break; default: ret = -EINVAL; } if (ret < 0) goto err; device_init_wakeup(max8998->dev, max8998->wakeup); return ret; err: mfd_remove_devices(max8998->dev); max8998_irq_exit(max8998); i2c_unregister_device(max8998->rtc); return ret; }
static int __devinit lpc_sch_probe(struct pci_dev *dev, const struct pci_device_id *id) { unsigned int base_addr_cfg; unsigned short base_addr; int i; int ret; pci_read_config_dword(dev, SMBASE, &base_addr_cfg); if (!(base_addr_cfg & (1 << 31))) { dev_err(&dev->dev, "Decode of the SMBus I/O range disabled\n"); return -ENODEV; } base_addr = (unsigned short)base_addr_cfg; if (base_addr == 0) { dev_err(&dev->dev, "I/O space for SMBus uninitialized\n"); return -ENODEV; } smbus_sch_resource.start = base_addr; smbus_sch_resource.end = base_addr + SMBUS_IO_SIZE - 1; pci_read_config_dword(dev, GPIOBASE, &base_addr_cfg); if (!(base_addr_cfg & (1 << 31))) { dev_err(&dev->dev, "Decode of the GPIO I/O range disabled\n"); return -ENODEV; } base_addr = (unsigned short)base_addr_cfg; if (base_addr == 0) { dev_err(&dev->dev, "I/O space for GPIO uninitialized\n"); return -ENODEV; } gpio_sch_resource.start = base_addr; gpio_sch_resource.end = base_addr + GPIO_IO_SIZE - 1; for (i=0; i < ARRAY_SIZE(lpc_sch_cells); i++) lpc_sch_cells[i].id = id->device; ret = mfd_add_devices(&dev->dev, 0, lpc_sch_cells, ARRAY_SIZE(lpc_sch_cells), NULL, 0); if (ret) goto out_dev; if (id->device == PCI_DEVICE_ID_INTEL_ITC_LPC) { pci_read_config_dword(dev, WDTBASE, &base_addr_cfg); if (!(base_addr_cfg & (1 << 31))) { dev_err(&dev->dev, "Decode of the WDT I/O range disabled\n"); ret = -ENODEV; goto out_dev; } base_addr = (unsigned short)base_addr_cfg; if (base_addr == 0) { dev_err(&dev->dev, "I/O space for WDT uninitialized\n"); ret = -ENODEV; goto out_dev; } wdt_sch_resource.start = base_addr; wdt_sch_resource.end = base_addr + WDT_IO_SIZE - 1; for (i = 0; i < ARRAY_SIZE(tunnelcreek_cells); i++) tunnelcreek_cells[i].id = id->device; ret = mfd_add_devices(&dev->dev, 0, tunnelcreek_cells, ARRAY_SIZE(tunnelcreek_cells), NULL, 0); } return ret; out_dev: mfd_remove_devices(&dev->dev); return ret; }
static int max77828_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct max77828_dev *max77828; struct max77828_platform_data *pdata = i2c->dev.platform_data; u8 reg_data; int ret = 0; dev_info(&i2c->dev, "%s\n", __func__); max77828 = kzalloc(sizeof(struct max77828_dev), GFP_KERNEL); if (!max77828) { dev_err(&i2c->dev, "%s: Failed to alloc mem for max77828\n", __func__); return -ENOMEM; } if (i2c->dev.of_node) { pdata = devm_kzalloc(&i2c->dev, sizeof(struct max77828_platform_data), GFP_KERNEL); if (!pdata) { dev_err(&i2c->dev, "Failed to allocate memory \n"); ret = -ENOMEM; goto err; } ret = of_max77828_dt(&i2c->dev, pdata); if (ret < 0){ dev_err(&i2c->dev, "Failed to get device of_node \n"); return ret; } /*pdata update to other modules*/ pdata->muic_data = &max77828_muic; #ifdef CONFIG_LEDS_MAX77828 pdata->led_data = &max77828_led_pdata; #endif i2c->dev.platform_data = pdata; } else pdata = i2c->dev.platform_data; max77828->dev = &i2c->dev; max77828->i2c = i2c; max77828->irq = i2c->irq; if (pdata) { max77828->pdata = pdata; max77828->irq_base = pdata->irq_base; max77828->irq_gpio = pdata->irq_gpio; max77828->wakeup = pdata->wakeup; gpio_tlmm_config(GPIO_CFG(max77828->irq_gpio, 0, GPIO_CFG_INPUT, GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_DISABLE); } else { ret = -EINVAL; goto err; } mutex_init(&max77828->iolock); i2c_set_clientdata(i2c, max77828); if (max77828_read_reg(i2c, MAX77828_PMIC_REG_PMICREV, ®_data) < 0) { dev_err(max77828->dev, "device not found on this channel (this is not an error)\n"); ret = -ENODEV; goto err; } else { /* print rev */ max77828->pmic_rev = (reg_data & 0x7); max77828->pmic_ver = ((reg_data & 0xF8) >> 0x3); pr_info("%s: device found: rev.0x%x, ver.0x%x\n", __func__, max77828->pmic_rev, max77828->pmic_ver); } max77828->muic = i2c_new_dummy(i2c->adapter, I2C_ADDR_MUIC); i2c_set_clientdata(max77828->muic, max77828); max77828->led = i2c_new_dummy(i2c->adapter, I2C_ADDR_LED); i2c_set_clientdata(max77828->led, max77828); ret = max77828_irq_init(max77828); if (ret < 0) goto err_irq_init; ret = mfd_add_devices(max77828->dev, -1, max77828_devs, ARRAY_SIZE(max77828_devs), NULL, 0); if (ret < 0) goto err_mfd; device_init_wakeup(max77828->dev, pdata->wakeup); return ret; err_mfd: mfd_remove_devices(max77828->dev); max77828_irq_exit(max77828); err_irq_init: i2c_unregister_device(max77828->muic); i2c_unregister_device(max77828->led); err: kfree(max77828); return ret; }
int cros_ec_register(struct cros_ec_device *ec_dev) { struct device *dev = ec_dev->dev; int err = 0; BLOCKING_INIT_NOTIFIER_HEAD(&ec_dev->event_notifier); ec_dev->max_request = sizeof(struct ec_params_hello); ec_dev->max_response = sizeof(struct ec_response_get_protocol_info); ec_dev->max_passthru = 0; ec_dev->din = devm_kzalloc(dev, ec_dev->din_size, GFP_KERNEL); if (!ec_dev->din) return -ENOMEM; ec_dev->dout = devm_kzalloc(dev, ec_dev->dout_size, GFP_KERNEL); if (!ec_dev->dout) return -ENOMEM; mutex_init(&ec_dev->lock); cros_ec_query_all(ec_dev); if (ec_dev->irq) { err = request_threaded_irq(ec_dev->irq, NULL, ec_irq_thread, IRQF_TRIGGER_LOW | IRQF_ONESHOT, "chromeos-ec", ec_dev); if (err) { dev_err(dev, "Failed to request IRQ %d: %d", ec_dev->irq, err); return err; } } err = mfd_add_devices(ec_dev->dev, PLATFORM_DEVID_AUTO, &ec_cell, 1, NULL, ec_dev->irq, NULL); if (err) { dev_err(dev, "Failed to register Embedded Controller subdevice %d\n", err); goto fail_mfd; } if (ec_dev->max_passthru) { /* * Register a PD device as well on top of this device. * We make the following assumptions: * - behind an EC, we have a pd * - only one device added. * - the EC is responsive at init time (it is not true for a * sensor hub. */ err = mfd_add_devices(ec_dev->dev, PLATFORM_DEVID_AUTO, &ec_pd_cell, 1, NULL, ec_dev->irq, NULL); if (err) { dev_err(dev, "Failed to register Power Delivery subdevice %d\n", err); goto fail_mfd; } } if (IS_ENABLED(CONFIG_OF) && dev->of_node) { err = of_platform_populate(dev->of_node, NULL, NULL, dev); if (err) { mfd_remove_devices(dev); dev_err(dev, "Failed to register sub-devices\n"); goto fail_mfd; } } /* * Clear sleep event - this will fail harmlessly on platforms that * don't implement the sleep event host command. */ err = cros_ec_sleep_event(ec_dev, 0); if (err < 0) dev_dbg(ec_dev->dev, "Error %d clearing sleep event to ec", err); dev_info(dev, "Chrome EC device registered\n"); return 0; fail_mfd: if (ec_dev->irq) free_irq(ec_dev->irq, ec_dev); return err; }
static int __init pasic3_probe(struct platform_device *pdev) { struct pasic3_platform_data *pdata = pdev->dev.platform_data; struct device *dev = &pdev->dev; struct pasic3_data *asic; struct resource *r; int ret; int irq = 0; r = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (r) { ds1wm_resources[1].flags = IORESOURCE_IRQ | (r->flags & (IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE)); irq = r->start; } r = platform_get_resource(pdev, IORESOURCE_IRQ, 0); if (r) { ds1wm_resources[1].flags = IORESOURCE_IRQ | (r->flags & (IORESOURCE_IRQ_HIGHEDGE | IORESOURCE_IRQ_LOWEDGE)); irq = r->start; } r = platform_get_resource(pdev, IORESOURCE_MEM, 0); if (!r) return -ENXIO; if (!request_mem_region(r->start, resource_size(r), "pasic3")) return -EBUSY; asic = kzalloc(sizeof(struct pasic3_data), GFP_KERNEL); if (!asic) return -ENOMEM; platform_set_drvdata(pdev, asic); asic->mapping = ioremap(r->start, resource_size(r)); if (!asic->mapping) { dev_err(dev, "couldn't ioremap PASIC3\n"); kfree(asic); return -ENOMEM; } /* calculate bus shift from mem resource */ asic->bus_shift = (resource_size(r) - 5) >> 3; if (pdata && pdata->clock_rate) { ds1wm_pdata.clock_rate = pdata->clock_rate; /* the first 5 PASIC3 registers control the DS1WM */ ds1wm_resources[0].end = (5 << asic->bus_shift) - 1; ds1wm_cell.platform_data = &ds1wm_cell; ds1wm_cell.data_size = sizeof(ds1wm_cell); ret = mfd_add_devices(&pdev->dev, pdev->id, &ds1wm_cell, 1, r, irq); if (ret < 0) dev_warn(dev, "failed to register DS1WM\n"); } if (pdata && pdata->led_pdata) { led_cell.driver_data = pdata->led_pdata; led_cell.platform_data = &led_cell; led_cell.data_size = sizeof(ds1wm_cell); ret = mfd_add_devices(&pdev->dev, pdev->id, &led_cell, 1, r, 0); if (ret < 0) dev_warn(dev, "failed to register LED device\n"); } return 0; }
static int si476x_core_probe(struct i2c_client *client, const struct i2c_device_id *id) { int rval; struct si476x_core *core; struct si476x_platform_data *pdata; struct mfd_cell *cell; int cell_num; core = devm_kzalloc(&client->dev, sizeof(*core), GFP_KERNEL); if (!core) { dev_err(&client->dev, "failed to allocate 'struct si476x_core'\n"); return -ENOMEM; } core->client = client; core->regmap = devm_regmap_init_si476x(core); if (IS_ERR(core->regmap)) { rval = PTR_ERR(core->regmap); dev_err(&client->dev, "Failed to allocate register map: %d\n", rval); return rval; } i2c_set_clientdata(client, core); atomic_set(&core->is_alive, 0); core->power_state = SI476X_POWER_DOWN; pdata = dev_get_platdata(&client->dev); if (pdata) { memcpy(&core->power_up_parameters, &pdata->power_up_parameters, sizeof(core->power_up_parameters)); core->gpio_reset = -1; if (gpio_is_valid(pdata->gpio_reset)) { rval = gpio_request(pdata->gpio_reset, "si476x reset"); if (rval) { dev_err(&client->dev, "Failed to request gpio: %d\n", rval); return rval; } core->gpio_reset = pdata->gpio_reset; gpio_direction_output(core->gpio_reset, 0); } core->diversity_mode = pdata->diversity_mode; memcpy(&core->pinmux, &pdata->pinmux, sizeof(struct si476x_pinmux)); } else { dev_err(&client->dev, "No platform data provided\n"); return -EINVAL; } core->supplies[0].supply = "vd"; core->supplies[1].supply = "va"; core->supplies[2].supply = "vio1"; core->supplies[3].supply = "vio2"; rval = devm_regulator_bulk_get(&client->dev, ARRAY_SIZE(core->supplies), core->supplies); if (rval) { dev_err(&client->dev, "Failet to gett all of the regulators\n"); goto free_gpio; } mutex_init(&core->cmd_lock); init_waitqueue_head(&core->command); init_waitqueue_head(&core->tuning); rval = kfifo_alloc(&core->rds_fifo, SI476X_DRIVER_RDS_FIFO_DEPTH * sizeof(struct v4l2_rds_data), GFP_KERNEL); if (rval) { dev_err(&client->dev, "Could not alloate the FIFO\n"); goto free_gpio; } mutex_init(&core->rds_drainer_status_lock); init_waitqueue_head(&core->rds_read_queue); INIT_WORK(&core->rds_fifo_drainer, si476x_core_drain_rds_fifo); if (client->irq) { rval = devm_request_threaded_irq(&client->dev, client->irq, NULL, si476x_core_interrupt, IRQF_TRIGGER_FALLING, client->name, core); if (rval < 0) { dev_err(&client->dev, "Could not request IRQ %d\n", client->irq); goto free_kfifo; } disable_irq(client->irq); dev_dbg(&client->dev, "IRQ requested.\n"); core->rds_fifo_depth = 20; } else { INIT_DELAYED_WORK(&core->status_monitor, si476x_core_poll_loop); dev_info(&client->dev, "No IRQ number specified, will use polling\n"); core->rds_fifo_depth = 5; } core->chip_id = id->driver_data; rval = si476x_core_get_revision_info(core); if (rval < 0) { rval = -ENODEV; goto free_kfifo; } cell_num = 0; cell = &core->cells[SI476X_RADIO_CELL]; cell->name = "si476x-radio"; cell_num++; #ifdef CONFIG_SND_SOC_SI476X if ((core->chip_id == SI476X_CHIP_SI4761 || core->chip_id == SI476X_CHIP_SI4764) && core->pinmux.dclk == SI476X_DCLK_DAUDIO && core->pinmux.dfs == SI476X_DFS_DAUDIO && core->pinmux.dout == SI476X_DOUT_I2S_OUTPUT && core->pinmux.xout == SI476X_XOUT_TRISTATE) { cell = &core->cells[SI476X_CODEC_CELL]; cell->name = "si476x-codec"; cell_num++; } #endif rval = mfd_add_devices(&client->dev, (client->adapter->nr << 8) + client->addr, core->cells, cell_num, NULL, 0, NULL); if (!rval) return 0; free_kfifo: kfifo_free(&core->rds_fifo); free_gpio: if (gpio_is_valid(core->gpio_reset)) gpio_free(core->gpio_reset); return rval; }
int da9063_device_init(struct da9063 *da9063, unsigned int irq) { struct da9063_pdata *pdata = da9063->dev->platform_data; int model, revision; int ret; if (pdata) { da9063->flags = pdata->flags; da9063->irq_base = pdata->irq_base; } else { da9063->flags = 0; da9063->irq_base = 0; } da9063->chip_irq = irq; if (pdata && pdata->init != NULL) { ret = pdata->init(da9063); if (ret != 0) { dev_err(da9063->dev, "Platform initialization failed.\n"); return ret; } } ret = regmap_read(da9063->regmap, DA9063_REG_CHIP_ID, &model); if (ret < 0) { dev_err(da9063->dev, "Cannot read chip model id.\n"); return -EIO; } if (model != PMIC_DA9063) { dev_err(da9063->dev, "Invalid chip model id: 0x%02x\n", model); return -ENODEV; } ret = regmap_read(da9063->regmap, DA9063_REG_CHIP_VARIANT, &revision); if (ret < 0) { dev_err(da9063->dev, "Cannot read chip revision id.\n"); return -EIO; } revision >>= DA9063_CHIP_VARIANT_SHIFT; if (revision != 3) { dev_err(da9063->dev, "Unknown chip revision: %d\n", revision); return -ENODEV; } da9063->model = model; da9063->revision = revision; dev_info(da9063->dev, "Device detected (model-ID: 0x%02X rev-ID: 0x%02X)\n", model, revision); ret = da9063_irq_init(da9063); if (ret) { dev_err(da9063->dev, "Cannot initialize interrupts.\n"); return ret; } ret = mfd_add_devices(da9063->dev, -1, da9063_devs, ARRAY_SIZE(da9063_devs), NULL, da9063->irq_base, NULL); if (ret) dev_err(da9063->dev, "Cannot add MFD cells\n"); return ret; }
static int aat2870_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) { struct aat2870_platform_data *pdata = dev_get_platdata(&client->dev); struct aat2870_data *aat2870; int i, j; int ret = 0; aat2870 = devm_kzalloc(&client->dev, sizeof(struct aat2870_data), GFP_KERNEL); if (!aat2870) { dev_err(&client->dev, "Failed to allocate memory for aat2870\n"); return -ENOMEM; } aat2870->dev = &client->dev; dev_set_drvdata(aat2870->dev, aat2870); aat2870->client = client; i2c_set_clientdata(client, aat2870); aat2870->reg_cache = aat2870_regs; if (pdata->en_pin < 0) aat2870->en_pin = -1; else aat2870->en_pin = pdata->en_pin; aat2870->init = pdata->init; aat2870->uninit = pdata->uninit; aat2870->read = aat2870_read; aat2870->write = aat2870_write; aat2870->update = aat2870_update; mutex_init(&aat2870->io_lock); if (aat2870->init) aat2870->init(aat2870); if (aat2870->en_pin >= 0) { ret = devm_gpio_request_one(&client->dev, aat2870->en_pin, GPIOF_OUT_INIT_HIGH, "aat2870-en"); if (ret < 0) { dev_err(&client->dev, "Failed to request GPIO %d\n", aat2870->en_pin); return ret; } } aat2870_enable(aat2870); for (i = 0; i < pdata->num_subdevs; i++) { for (j = 0; j < ARRAY_SIZE(aat2870_devs); j++) { if ((pdata->subdevs[i].id == aat2870_devs[j].id) && !strcmp(pdata->subdevs[i].name, aat2870_devs[j].name)) { aat2870_devs[j].platform_data = pdata->subdevs[i].platform_data; break; } } } ret = mfd_add_devices(aat2870->dev, 0, aat2870_devs, ARRAY_SIZE(aat2870_devs), NULL, 0, NULL); if (ret != 0) { dev_err(aat2870->dev, "Failed to add subdev: %d\n", ret); goto out_disable; } aat2870_init_debugfs(aat2870); return 0; out_disable: aat2870_disable(aat2870); return ret; }
static int t7l66xb_probe(struct platform_device *dev) { struct t7l66xb_platform_data *pdata = dev->dev.platform_data; struct t7l66xb *t7l66xb; struct resource *iomem, *rscr; int ret; if (pdata == NULL) return -EINVAL; iomem = platform_get_resource(dev, IORESOURCE_MEM, 0); if (!iomem) return -EINVAL; t7l66xb = kzalloc(sizeof *t7l66xb, GFP_KERNEL); if (!t7l66xb) return -ENOMEM; spin_lock_init(&t7l66xb->lock); platform_set_drvdata(dev, t7l66xb); ret = platform_get_irq(dev, 0); if (ret >= 0) t7l66xb->irq = ret; else goto err_noirq; t7l66xb->irq_base = pdata->irq_base; t7l66xb->clk32k = clk_get(&dev->dev, "CLK_CK32K"); if (IS_ERR(t7l66xb->clk32k)) { ret = PTR_ERR(t7l66xb->clk32k); goto err_clk32k_get; } t7l66xb->clk48m = clk_get(&dev->dev, "CLK_CK48M"); if (IS_ERR(t7l66xb->clk48m)) { ret = PTR_ERR(t7l66xb->clk48m); goto err_clk48m_get; } rscr = &t7l66xb->rscr; rscr->name = "t7l66xb-core"; rscr->start = iomem->start; rscr->end = iomem->start + 0xff; rscr->flags = IORESOURCE_MEM; ret = request_resource(iomem, rscr); if (ret) goto err_request_scr; t7l66xb->scr = ioremap(rscr->start, resource_size(rscr)); if (!t7l66xb->scr) { ret = -ENOMEM; goto err_ioremap; } clk_enable(t7l66xb->clk48m); if (pdata && pdata->enable) pdata->enable(dev); /* Mask all interrupts */ tmio_iowrite8(0xbf, t7l66xb->scr + SCR_IMR); printk(KERN_INFO "%s rev %d @ 0x%08lx, irq %d\n", dev->name, tmio_ioread8(t7l66xb->scr + SCR_REVID), (unsigned long)iomem->start, t7l66xb->irq); t7l66xb_attach_irq(dev); t7l66xb_cells[T7L66XB_CELL_NAND].platform_data = pdata->nand_data; t7l66xb_cells[T7L66XB_CELL_NAND].pdata_size = sizeof(*pdata->nand_data); ret = mfd_add_devices(&dev->dev, dev->id, t7l66xb_cells, ARRAY_SIZE(t7l66xb_cells), iomem, t7l66xb->irq_base); if (!ret) return 0; t7l66xb_detach_irq(dev); iounmap(t7l66xb->scr); err_ioremap: release_resource(&t7l66xb->rscr); err_request_scr: clk_put(t7l66xb->clk48m); err_clk48m_get: clk_put(t7l66xb->clk32k); err_clk32k_get: err_noirq: kfree(t7l66xb); return ret; }
static int max77804_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *dev_id) { struct max77804_dev *max77804; struct max77804_platform_data *pdata = i2c->dev.platform_data; u8 reg_data; int ret = 0; pr_info("%s:%s\n", MFD_DEV_NAME, __func__); max77804 = kzalloc(sizeof(struct max77804_dev), GFP_KERNEL); if (!max77804) { dev_err(&i2c->dev, "%s: Failed to alloc mem for max77804\n", __func__); return -ENOMEM; } if (i2c->dev.of_node) { pdata = devm_kzalloc(&i2c->dev, sizeof(struct max77804_platform_data), GFP_KERNEL); if (!pdata) { dev_err(&i2c->dev, "Failed to allocate memory \n"); ret = -ENOMEM; goto err; } ret = of_max77804_dt(&i2c->dev, pdata); if (ret < 0){ dev_err(&i2c->dev, "Failed to get device of_node \n"); return ret; } i2c->dev.platform_data = pdata; } else pdata = i2c->dev.platform_data; max77804->dev = &i2c->dev; max77804->i2c = i2c; max77804->irq = i2c->irq; if (pdata) { max77804->pdata = pdata; pdata->irq_base = irq_alloc_descs(-1, 0, MAX77804_IRQ_NR, -1); if (pdata->irq_base < 0) { pr_err("%s:%s irq_alloc_descs Fail! ret(%d)\n", MFD_DEV_NAME, __func__, pdata->irq_base); ret = -EINVAL; goto err; } else max77804->irq_base = pdata->irq_base; max77804->irq_gpio = pdata->irq_gpio; max77804->wakeup = pdata->wakeup; } else { ret = -EINVAL; goto err; } mutex_init(&max77804->i2c_lock); i2c_set_clientdata(i2c, max77804); if (max77804_read_reg(i2c, MAX77804_PMIC_REG_PMIC_ID2, ®_data) < 0) { dev_err(max77804->dev, "device not found on this channel (this is not an error)\n"); ret = -ENODEV; goto err; } else { /* print rev */ max77804->pmic_rev = (reg_data & 0x7); max77804->pmic_ver = ((reg_data & 0xF8) >> 0x3); pr_info("%s:%s device found: rev.0x%x, ver.0x%x\n", MFD_DEV_NAME, __func__, max77804->pmic_rev, max77804->pmic_ver); } /* No active discharge on safeout ldo 1,2 */ max77804_update_reg(i2c, MAX77804_CHG_REG_SAFEOUT_CTRL, 0x00, 0x30); max77804->muic = i2c_new_dummy(i2c->adapter, I2C_ADDR_MUIC); i2c_set_clientdata(max77804->muic, max77804); max77804->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC); i2c_set_clientdata(max77804->haptic, max77804); #if defined(CONFIG_MFD_MAX77804) ret = max77804_irq_init(max77804); #elif defined(CONFIG_MFD_MAX77804K) ret = max77804k_irq_init(max77804); #endif if (ret < 0) goto err_irq_init; ret = mfd_add_devices(max77804->dev, -1, max77804_devs, ARRAY_SIZE(max77804_devs), NULL, 0, NULL); if (ret < 0) goto err_mfd; device_init_wakeup(max77804->dev, pdata->wakeup); return ret; err_mfd: mfd_remove_devices(max77804->dev); err_irq_init: i2c_unregister_device(max77804->muic); i2c_unregister_device(max77804->haptic); err: kfree(max77804); return ret; }
static int max77693_i2c_probe(struct i2c_client *i2c, const struct i2c_device_id *id) { struct max77693_dev *max77693; struct max77693_platform_data *pdata = i2c->dev.platform_data; u8 reg_data; int ret = 0; max77693 = kzalloc(sizeof(struct max77693_dev), GFP_KERNEL); if (max77693 == NULL) return -ENOMEM; i2c_set_clientdata(i2c, max77693); max77693->dev = &i2c->dev; max77693->i2c = i2c; max77693->irq = i2c->irq; max77693->type = id->driver_data; if (pdata) { max77693->irq_base = pdata->irq_base; max77693->irq_gpio = pdata->irq_gpio; max77693->wakeup = pdata->wakeup; } else goto err; mutex_init(&max77693->iolock); if (max77693_read_reg(i2c, MAX77693_PMIC_REG_PMIC_ID2, ®_data) < 0) { dev_err(max77693->dev, "device not found on this channel (this is not an error)\n"); ret = -ENODEV; goto err; } else { /* print rev */ max77693->pmic_rev = (reg_data & 0x7); max77693->pmic_ver = ((reg_data & 0xF8) >> 0x3); pr_info("%s: device found: rev.0x%x, ver.0x%x\n", __func__, max77693->pmic_rev, max77693->pmic_ver); } #if 0 #if defined(CONFIG_MACH_JF_VZW) || defined(CONFIG_MACH_JF_LGT) if (kernel_sec_get_debug_level() == KERNEL_SEC_DEBUG_LEVEL_LOW) { pm8xxx_hard_reset_config(PM8XXX_DISABLE_HARD_RESET); max77693_write_reg(i2c, MAX77693_PMIC_REG_MAINCTRL1, 0x04); } else { pm8xxx_hard_reset_config(PM8XXX_DISABLE_HARD_RESET); max77693_write_reg(i2c, MAX77693_PMIC_REG_MAINCTRL1, 0x0c); } #else if (kernel_sec_get_debug_level() == KERNEL_SEC_DEBUG_LEVEL_LOW) { max77693_write_reg(i2c, MAX77693_PMIC_REG_MAINCTRL1, 0x04); } else { pm8xxx_hard_reset_config(PM8XXX_DISABLE_HARD_RESET); max77693_write_reg(i2c, MAX77693_PMIC_REG_MAINCTRL1, 0x0c); } #endif #endif #if defined(CONFIG_MACH_SERRANO_VZW) if (kernel_sec_get_debug_level() == KERNEL_SEC_DEBUG_LEVEL_LOW) { #if defined(CONFIG_SEC_DISABLE_HARDRESET) pm8xxx_hard_reset_config(PM8XXX_DISABLE_HARD_RESET); #endif max77693_write_reg(i2c, MAX77693_PMIC_REG_MAINCTRL1, 0x04); } else { pm8xxx_hard_reset_config(PM8XXX_DISABLE_HARD_RESET); max77693_write_reg(i2c, MAX77693_PMIC_REG_MAINCTRL1, 0x0c); } #endif max77693_update_reg(i2c, MAX77693_CHG_REG_SAFEOUT_CTRL, 0x00, 0x30); max77693->muic = i2c_new_dummy(i2c->adapter, I2C_ADDR_MUIC); i2c_set_clientdata(max77693->muic, max77693); max77693->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC); i2c_set_clientdata(max77693->haptic, max77693); ret = max77693_irq_init(max77693); if (ret < 0) goto err_irq_init; ret = mfd_add_devices(max77693->dev, -1, max77693_devs, ARRAY_SIZE(max77693_devs), NULL, 0); if (ret < 0) goto err_mfd; device_init_wakeup(max77693->dev, pdata->wakeup); return ret; err_mfd: mfd_remove_devices(max77693->dev); err_irq_init: i2c_unregister_device(max77693->muic); i2c_unregister_device(max77693->haptic); err: kfree(max77693); return ret; }
/* * Instantiate the generic non-control parts of the device. */ static __devinit int wm8994_device_init(struct wm8994 *wm8994, int irq) { struct wm8994_pdata *pdata = wm8994->dev->platform_data; struct regmap_config *regmap_config; const struct reg_default *regmap_patch = NULL; const char *devname; int ret, i, patch_regs; int pulls = 0; dev_set_drvdata(wm8994->dev, wm8994); /* Add the on-chip regulators first for bootstrapping */ ret = mfd_add_devices(wm8994->dev, -1, wm8994_regulator_devs, ARRAY_SIZE(wm8994_regulator_devs), NULL, 0, NULL); if (ret != 0) { dev_err(wm8994->dev, "Failed to add children: %d\n", ret); goto err; } switch (wm8994->type) { case WM1811: wm8994->num_supplies = ARRAY_SIZE(wm1811_main_supplies); break; case WM8994: wm8994->num_supplies = ARRAY_SIZE(wm8994_main_supplies); break; case WM8958: wm8994->num_supplies = ARRAY_SIZE(wm8958_main_supplies); break; default: BUG(); goto err; } wm8994->supplies = devm_kzalloc(wm8994->dev, sizeof(struct regulator_bulk_data) * wm8994->num_supplies, GFP_KERNEL); if (!wm8994->supplies) { ret = -ENOMEM; goto err; } switch (wm8994->type) { case WM1811: for (i = 0; i < ARRAY_SIZE(wm1811_main_supplies); i++) wm8994->supplies[i].supply = wm1811_main_supplies[i]; break; case WM8994: for (i = 0; i < ARRAY_SIZE(wm8994_main_supplies); i++) wm8994->supplies[i].supply = wm8994_main_supplies[i]; break; case WM8958: for (i = 0; i < ARRAY_SIZE(wm8958_main_supplies); i++) wm8994->supplies[i].supply = wm8958_main_supplies[i]; break; default: BUG(); goto err; } ret = regulator_bulk_get(wm8994->dev, wm8994->num_supplies, wm8994->supplies); if (ret != 0) { dev_err(wm8994->dev, "Failed to get supplies: %d\n", ret); goto err; } ret = regulator_bulk_enable(wm8994->num_supplies, wm8994->supplies); if (ret != 0) { dev_err(wm8994->dev, "Failed to enable supplies: %d\n", ret); goto err_get; } ret = wm8994_reg_read(wm8994, WM8994_SOFTWARE_RESET); if (ret < 0) { dev_err(wm8994->dev, "Failed to read ID register\n"); goto err_enable; } switch (ret) { case 0x1811: devname = "WM1811"; if (wm8994->type != WM1811) dev_warn(wm8994->dev, "Device registered as type %d\n", wm8994->type); wm8994->type = WM1811; break; case 0x8994: devname = "WM8994"; if (wm8994->type != WM8994) dev_warn(wm8994->dev, "Device registered as type %d\n", wm8994->type); wm8994->type = WM8994; break; case 0x8958: devname = "WM8958"; if (wm8994->type != WM8958) dev_warn(wm8994->dev, "Device registered as type %d\n", wm8994->type); wm8994->type = WM8958; break; default: dev_err(wm8994->dev, "Device is not a WM8994, ID is %x\n", ret); ret = -EINVAL; goto err_enable; } ret = wm8994_reg_read(wm8994, WM8994_CHIP_REVISION); if (ret < 0) { dev_err(wm8994->dev, "Failed to read revision register: %d\n", ret); goto err_enable; } wm8994->revision = ret & WM8994_CHIP_REV_MASK; wm8994->cust_id = (ret & WM8994_CUST_ID_MASK) >> WM8994_CUST_ID_SHIFT; switch (wm8994->type) { case WM8994: switch (wm8994->revision) { case 0: case 1: dev_warn(wm8994->dev, "revision %c not fully supported\n", 'A' + wm8994->revision); break; case 2: case 3: regmap_patch = wm8994_revc_patch; patch_regs = ARRAY_SIZE(wm8994_revc_patch); break; default: break; } break; case WM8958: switch (wm8994->revision) { case 0: regmap_patch = wm8958_reva_patch; patch_regs = ARRAY_SIZE(wm8958_reva_patch); break; default: break; } break; case WM1811: /* Revision C did not change the relevant layer */ if (wm8994->revision > 1) wm8994->revision++; switch (wm8994->revision) { case 0: case 1: case 2: case 3: regmap_patch = wm1811_reva_patch; patch_regs = ARRAY_SIZE(wm1811_reva_patch); break; default: break; } break; default: break; } dev_info(wm8994->dev, "%s revision %c CUST_ID %02x\n", devname, 'A' + wm8994->revision, wm8994->cust_id); switch (wm8994->type) { case WM1811: regmap_config = &wm1811_regmap_config; break; case WM8994: regmap_config = &wm8994_regmap_config; break; case WM8958: regmap_config = &wm8958_regmap_config; break; default: dev_err(wm8994->dev, "Unknown device type %d\n", wm8994->type); return -EINVAL; } ret = regmap_reinit_cache(wm8994->regmap, regmap_config); if (ret != 0) { dev_err(wm8994->dev, "Failed to reinit register cache: %d\n", ret); return ret; } if (regmap_patch) { ret = regmap_register_patch(wm8994->regmap, regmap_patch, patch_regs); if (ret != 0) { dev_err(wm8994->dev, "Failed to register patch: %d\n", ret); goto err; } } if (pdata) { wm8994->irq_base = pdata->irq_base; wm8994->gpio_base = pdata->gpio_base; /* GPIO configuration is only applied if it's non-zero */ for (i = 0; i < ARRAY_SIZE(pdata->gpio_defaults); i++) { if (pdata->gpio_defaults[i]) { wm8994_set_bits(wm8994, WM8994_GPIO_1 + i, 0xffff, pdata->gpio_defaults[i]); } } wm8994->ldo_ena_always_driven = pdata->ldo_ena_always_driven; if (pdata->spkmode_pu) pulls |= WM8994_SPKMODE_PU; } /* Disable unneeded pulls */ wm8994_set_bits(wm8994, WM8994_PULL_CONTROL_2, WM8994_LDO1ENA_PD | WM8994_LDO2ENA_PD | WM8994_SPKMODE_PU | WM8994_CSNADDR_PD, pulls); /* In some system designs where the regulators are not in use, * we can achieve a small reduction in leakage currents by * floating LDO outputs. This bit makes no difference if the * LDOs are enabled, it only affects cases where the LDOs were * in operation and are then disabled. */ for (i = 0; i < WM8994_NUM_LDO_REGS; i++) { if (wm8994_ldo_in_use(pdata, i)) wm8994_set_bits(wm8994, WM8994_LDO_1 + i, WM8994_LDO1_DISCH, WM8994_LDO1_DISCH); else wm8994_set_bits(wm8994, WM8994_LDO_1 + i, WM8994_LDO1_DISCH, 0); } wm8994_irq_init(wm8994); ret = mfd_add_devices(wm8994->dev, -1, wm8994_devs, ARRAY_SIZE(wm8994_devs), NULL, 0, NULL); if (ret != 0) { dev_err(wm8994->dev, "Failed to add children: %d\n", ret); goto err_irq; } pm_runtime_enable(wm8994->dev); pm_runtime_idle(wm8994->dev); return 0; err_irq: wm8994_irq_exit(wm8994); err_enable: regulator_bulk_disable(wm8994->num_supplies, wm8994->supplies); err_get: regulator_bulk_free(wm8994->num_supplies, wm8994->supplies); err: mfd_remove_devices(wm8994->dev); return ret; }
int __devinit arizona_dev_init(struct arizona *arizona) { struct device *dev = arizona->dev; const char *type_name; unsigned int reg, val; int (*apply_patch)(struct arizona *) = NULL; int ret, i; dev_set_drvdata(arizona->dev, arizona); mutex_init(&arizona->clk_lock); if (dev_get_platdata(arizona->dev)) memcpy(&arizona->pdata, dev_get_platdata(arizona->dev), sizeof(arizona->pdata)); regcache_cache_only(arizona->regmap, true); switch (arizona->type) { case WM5102: case WM5110: for (i = 0; i < ARRAY_SIZE(wm5102_core_supplies); i++) arizona->core_supplies[i].supply = wm5102_core_supplies[i]; arizona->num_core_supplies = ARRAY_SIZE(wm5102_core_supplies); break; default: dev_err(arizona->dev, "Unknown device type %d\n", arizona->type); return -EINVAL; } ret = mfd_add_devices(arizona->dev, -1, early_devs, ARRAY_SIZE(early_devs), NULL, 0); if (ret != 0) { dev_err(dev, "Failed to add early children: %d\n", ret); return ret; } ret = devm_regulator_bulk_get(dev, arizona->num_core_supplies, arizona->core_supplies); if (ret != 0) { dev_err(dev, "Failed to request core supplies: %d\n", ret); goto err_early; } arizona->dcvdd = devm_regulator_get(arizona->dev, "DCVDD"); if (IS_ERR(arizona->dcvdd)) { ret = PTR_ERR(arizona->dcvdd); dev_err(dev, "Failed to request DCVDD: %d\n", ret); goto err_early; } if (arizona->pdata.reset) { /* Start out with /RESET low to put the chip into reset */ ret = gpio_request_one(arizona->pdata.reset, GPIOF_DIR_OUT | GPIOF_INIT_LOW, "arizona /RESET"); if (ret != 0) { dev_err(dev, "Failed to request /RESET: %d\n", ret); goto err_early; } } ret = regulator_bulk_enable(arizona->num_core_supplies, arizona->core_supplies); if (ret != 0) { dev_err(dev, "Failed to enable core supplies: %d\n", ret); goto err_early; } ret = regulator_enable(arizona->dcvdd); if (ret != 0) { dev_err(dev, "Failed to enable DCVDD: %d\n", ret); goto err_enable; } if (arizona->pdata.control_init_time) msleep(arizona->pdata.control_init_time); if (arizona->pdata.reset) { gpio_set_value_cansleep(arizona->pdata.reset, 1); msleep(1); } regcache_cache_only(arizona->regmap, false); ret = regmap_read(arizona->regmap, ARIZONA_SOFTWARE_RESET, ®); if (ret != 0) { dev_err(dev, "Failed to read ID register: %d\n", ret); goto err_reset; } ret = regmap_read(arizona->regmap, ARIZONA_DEVICE_REVISION, &arizona->rev); if (ret != 0) { dev_err(dev, "Failed to read revision register: %d\n", ret); goto err_reset; } arizona->rev &= ARIZONA_DEVICE_REVISION_MASK; switch (reg) { #ifdef CONFIG_MFD_WM5102 case 0x5102: type_name = "WM5102"; if (arizona->type != WM5102) { dev_err(arizona->dev, "WM5102 registered as %d\n", arizona->type); arizona->type = WM5102; } apply_patch = wm5102_patch; arizona->rev &= 0x7; break; #endif #ifdef CONFIG_MFD_WM5110 case 0x5110: type_name = "WM5110"; if (arizona->type != WM5110) { dev_err(arizona->dev, "WM5110 registered as %d\n", arizona->type); arizona->type = WM5110; } apply_patch = wm5110_patch; break; #endif default: dev_err(arizona->dev, "Unknown device ID %x\n", reg); goto err_reset; } dev_info(dev, "%s revision %c\n", type_name, arizona->rev + 'A'); /* If we have a /RESET GPIO we'll already be reset */ if (!arizona->pdata.reset) { ret = regmap_write(arizona->regmap, ARIZONA_SOFTWARE_RESET, 0); if (ret != 0) { dev_err(dev, "Failed to reset device: %d\n", ret); goto err_reset; } msleep(1); } switch (arizona->type) { case WM5102: ret = regmap_read(arizona->regmap, 0x19, &val); if (ret != 0) dev_err(dev, "Failed to check write sequencer state: %d\n", ret); else if (val & 0x01) break; /* Fall through */ default: ret = arizona_wait_for_boot(arizona); if (ret != 0) { dev_err(arizona->dev, "Device failed initial boot: %d\n", ret); goto err_reset; } break; } if (apply_patch) { ret = apply_patch(arizona); if (ret != 0) { dev_err(arizona->dev, "Failed to apply patch: %d\n", ret); goto err_reset; } switch (arizona->type) { case WM5102: ret = arizona_apply_hardware_patch(arizona); if (ret != 0) { dev_err(arizona->dev, "Failed to apply hardware patch: %d\n", ret); goto err_reset; } break; default: break; } } for (i = 0; i < ARRAY_SIZE(arizona->pdata.gpio_defaults); i++) { if (!arizona->pdata.gpio_defaults[i]) continue; regmap_write(arizona->regmap, ARIZONA_GPIO1_CTRL + i, arizona->pdata.gpio_defaults[i]); } pm_runtime_enable(arizona->dev); /* Chip default */ if (!arizona->pdata.clk32k_src) arizona->pdata.clk32k_src = ARIZONA_32KZ_MCLK2; switch (arizona->pdata.clk32k_src) { case ARIZONA_32KZ_MCLK1: case ARIZONA_32KZ_MCLK2: regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1, ARIZONA_CLK_32K_SRC_MASK, arizona->pdata.clk32k_src - 1); arizona_clk32k_enable(arizona); break; case ARIZONA_32KZ_NONE: regmap_update_bits(arizona->regmap, ARIZONA_CLOCK_32K_1, ARIZONA_CLK_32K_SRC_MASK, 2); break; default: dev_err(arizona->dev, "Invalid 32kHz clock source: %d\n", arizona->pdata.clk32k_src); ret = -EINVAL; goto err_reset; } for (i = 0; i < ARIZONA_MAX_MICBIAS; i++) { if (!arizona->pdata.micbias[i].mV && !arizona->pdata.micbias[i].bypass) continue; /* Apply default for bypass mode */ if (!arizona->pdata.micbias[i].mV) arizona->pdata.micbias[i].mV = 2800; val = (arizona->pdata.micbias[i].mV - 1500) / 100; val <<= ARIZONA_MICB1_LVL_SHIFT; if (arizona->pdata.micbias[i].ext_cap) val |= ARIZONA_MICB1_EXT_CAP; if (arizona->pdata.micbias[i].discharge) val |= ARIZONA_MICB1_DISCH; if (arizona->pdata.micbias[i].fast_start) val |= ARIZONA_MICB1_RATE; if (arizona->pdata.micbias[i].bypass) val |= ARIZONA_MICB1_BYPASS; regmap_update_bits(arizona->regmap, ARIZONA_MIC_BIAS_CTRL_1 + i, ARIZONA_MICB1_LVL_MASK | ARIZONA_MICB1_DISCH | ARIZONA_MICB1_BYPASS | ARIZONA_MICB1_RATE, val); } for (i = 0; i < ARIZONA_MAX_INPUT; i++) { /* Default for both is 0 so noop with defaults */ val = arizona->pdata.dmic_ref[i] << ARIZONA_IN1_DMIC_SUP_SHIFT; val |= arizona->pdata.inmode[i] << ARIZONA_IN1_MODE_SHIFT; regmap_update_bits(arizona->regmap, ARIZONA_IN1L_CONTROL + (i * 8), ARIZONA_IN1_DMIC_SUP_MASK | ARIZONA_IN1_MODE_MASK, val); } for (i = 0; i < ARIZONA_MAX_OUTPUT; i++) { /* Default is 0 so noop with defaults */ if (arizona->pdata.out_mono[i]) val = ARIZONA_OUT1_MONO; else val = 0; regmap_update_bits(arizona->regmap, ARIZONA_OUTPUT_PATH_CONFIG_1L + (i * 8), ARIZONA_OUT1_MONO, val); } for (i = 0; i < ARIZONA_MAX_PDM_SPK; i++) { if (arizona->pdata.spk_mute[i]) regmap_update_bits(arizona->regmap, ARIZONA_PDM_SPK1_CTRL_1 + (i * 2), ARIZONA_SPK1_MUTE_ENDIAN_MASK | ARIZONA_SPK1_MUTE_SEQ1_MASK, arizona->pdata.spk_mute[i]); if (arizona->pdata.spk_fmt[i]) regmap_update_bits(arizona->regmap, ARIZONA_PDM_SPK1_CTRL_2 + (i * 2), ARIZONA_SPK1_FMT_MASK, arizona->pdata.spk_fmt[i]); } /* set virtual IRQs */ arizona->virq[0] = arizona->pdata.irq_base; arizona->virq[1] = arizona->pdata.irq_base + ARIZONA_NUM_IRQ; switch (arizona->pdata.mic_spk_clamp) { case ARIZONA_MIC_CLAMP_SPKLN: regmap_update_bits(arizona->regmap, ARIZONA_SPK_CTRL_2, 0x3c, 0xc); break; case ARIZONA_MIC_CLAMP_SPKLP: regmap_update_bits(arizona->regmap, ARIZONA_SPK_CTRL_2, 0x3c, 0x1c); break; case ARIZONA_MIC_CLAMP_SPKRN: regmap_update_bits(arizona->regmap, ARIZONA_SPK_CTRL_3, 0x3c, 0xc); break; case ARIZONA_MIC_CLAMP_SPKRP: regmap_update_bits(arizona->regmap, ARIZONA_SPK_CTRL_3, 0x3c, 0x1c); break; default: break; } /* Set up for interrupts */ ret = arizona_irq_init(arizona); if (ret != 0) goto err_reset; arizona_request_irq(arizona, ARIZONA_IRQ_CLKGEN_ERR, "CLKGEN error", arizona_clkgen_err, arizona); arizona_request_irq(arizona, ARIZONA_IRQ_OVERCLOCKED, "Overclocked", arizona_overclocked, arizona); arizona_request_irq(arizona, ARIZONA_IRQ_UNDERCLOCKED, "Underclocked", arizona_underclocked, arizona); switch (arizona->type) { case WM5102: ret = mfd_add_devices(arizona->dev, -1, wm5102_devs, ARRAY_SIZE(wm5102_devs), NULL, 0); break; case WM5110: ret = mfd_add_devices(arizona->dev, -1, wm5110_devs, ARRAY_SIZE(wm5110_devs), NULL, 0); break; } if (ret != 0) { dev_err(arizona->dev, "Failed to add subdevices: %d\n", ret); goto err_irq; } if (arizona->pdata.init_done) arizona->pdata.init_done(); #ifdef CONFIG_PM_RUNTIME regulator_disable(arizona->dcvdd); #endif return 0; err_irq: arizona_irq_exit(arizona); err_reset: if (arizona->pdata.reset) { gpio_set_value_cansleep(arizona->pdata.reset, 0); gpio_free(arizona->pdata.reset); } regulator_disable(arizona->dcvdd); err_enable: regulator_bulk_disable(arizona->num_core_supplies, arizona->core_supplies); err_early: mfd_remove_devices(dev); return ret; }
static int __devinit pm8921_add_subdevices(const struct pm8921_platform_data *pdata, struct pm8921 *pmic) { int ret = 0, irq_base = 0; struct pm_irq_chip *irq_chip; enum pm8xxx_version version; version = pm8xxx_get_version(pmic->dev); if (pdata->irq_pdata) { pdata->irq_pdata->irq_cdata.nirqs = PM8921_NR_IRQS; pdata->irq_pdata->irq_cdata.base_addr = REG_IRQ_BASE; irq_base = pdata->irq_pdata->irq_base; irq_chip = pm8xxx_irq_init(pmic->dev, pdata->irq_pdata); if (IS_ERR(irq_chip)) { pr_err("Failed to init interrupts ret=%ld\n", PTR_ERR(irq_chip)); return PTR_ERR(irq_chip); } pmic->irq_chip = irq_chip; } if (pdata->gpio_pdata) { if (version == PM8XXX_VERSION_8917) { gpio_cell_resources[0].end = gpio_cell_resources[0].end + PM8917_NR_GPIOS - PM8921_NR_GPIOS; pdata->gpio_pdata->gpio_cdata.ngpios = PM8917_NR_GPIOS; } else { pdata->gpio_pdata->gpio_cdata.ngpios = PM8921_NR_GPIOS; } gpio_cell.platform_data = pdata->gpio_pdata; gpio_cell.pdata_size = sizeof(struct pm8xxx_gpio_platform_data); ret = mfd_add_devices(pmic->dev, 0, &gpio_cell, 1, NULL, irq_base); if (ret) { pr_err("Failed to add gpio subdevice ret=%d\n", ret); goto bail; } } if (pdata->mpp_pdata) { if (version == PM8XXX_VERSION_8917) { mpp_cell_resources[0].end = mpp_cell_resources[0].end + PM8917_NR_MPPS - PM8921_NR_MPPS; pdata->mpp_pdata->core_data.nmpps = PM8917_NR_MPPS; } else { pdata->mpp_pdata->core_data.nmpps = PM8921_NR_MPPS; } pdata->mpp_pdata->core_data.base_addr = REG_MPP_BASE; mpp_cell.platform_data = pdata->mpp_pdata; mpp_cell.pdata_size = sizeof(struct pm8xxx_mpp_platform_data); ret = mfd_add_devices(pmic->dev, 0, &mpp_cell, 1, NULL, irq_base); if (ret) { pr_err("Failed to add mpp subdevice ret=%d\n", ret); goto bail; } } if (pdata->rtc_pdata) { rtc_cell.platform_data = pdata->rtc_pdata; rtc_cell.pdata_size = sizeof(struct pm8xxx_rtc_platform_data); ret = mfd_add_devices(pmic->dev, 0, &rtc_cell, 1, NULL, irq_base); if (ret) { pr_err("Failed to add rtc subdevice ret=%d\n", ret); goto bail; } } if (pdata->pwrkey_pdata) { pwrkey_cell.platform_data = pdata->pwrkey_pdata; pwrkey_cell.pdata_size = sizeof(struct pm8xxx_pwrkey_platform_data); ret = mfd_add_devices(pmic->dev, 0, &pwrkey_cell, 1, NULL, irq_base); if (ret) { pr_err("Failed to add pwrkey subdevice ret=%d\n", ret); goto bail; } } if (pdata->keypad_pdata) { keypad_cell.platform_data = pdata->keypad_pdata; keypad_cell.pdata_size = sizeof(struct pm8xxx_keypad_platform_data); ret = mfd_add_devices(pmic->dev, 0, &keypad_cell, 1, NULL, irq_base); if (ret) { pr_err("Failed to add keypad subdevice ret=%d\n", ret); goto bail; } } if (pdata->charger_pdata) { pdata->charger_pdata->charger_cdata.vbat_channel = CHANNEL_VBAT; pdata->charger_pdata->charger_cdata.batt_temp_channel = CHANNEL_BATT_THERM; pdata->charger_pdata->charger_cdata.batt_id_channel = CHANNEL_BATT_ID; charger_cell.platform_data = pdata->charger_pdata; charger_cell.pdata_size = sizeof(struct pm8921_charger_platform_data); ret = mfd_add_devices(pmic->dev, 0, &charger_cell, 1, NULL, irq_base); if (ret) { pr_err("Failed to add charger subdevice ret=%d\n", ret); goto bail; } } if (pdata->adc_pdata) { adc_cell.platform_data = pdata->adc_pdata; adc_cell.pdata_size = sizeof(struct pm8xxx_adc_platform_data); ret = mfd_add_devices(pmic->dev, 0, &adc_cell, 1, NULL, irq_base); if (ret) { pr_err("Failed to add regulator subdevices ret=%d\n", ret); } } if (pdata->bms_pdata) { pdata->bms_pdata->bms_cdata.batt_temp_channel = CHANNEL_BATT_THERM; pdata->bms_pdata->bms_cdata.vbat_channel = CHANNEL_VBAT; pdata->bms_pdata->bms_cdata.ref625mv_channel = CHANNEL_625MV; pdata->bms_pdata->bms_cdata.ref1p25v_channel = CHANNEL_125V; pdata->bms_pdata->bms_cdata.batt_id_channel = CHANNEL_BATT_ID; bms_cell.platform_data = pdata->bms_pdata; bms_cell.pdata_size = sizeof(struct pm8921_bms_platform_data); ret = mfd_add_devices(pmic->dev, 0, &bms_cell, 1, NULL, irq_base); if (ret) { pr_err("Failed to add bms subdevice ret=%d\n", ret); goto bail; } } if (pdata->num_regulators > 0 && pdata->regulator_pdatas) { ret = pm8921_add_regulators(pdata, pmic, irq_base); if (ret) { pr_err("Failed to add regulator subdevices ret=%d\n", ret); goto bail; } } ret = mfd_add_devices(pmic->dev, 0, &debugfs_cell, 1, NULL, irq_base); if (ret) { pr_err("Failed to add debugfs subdevice ret=%d\n", ret); goto bail; } if (pdata->misc_pdata) { misc_cell.platform_data = pdata->misc_pdata; misc_cell.pdata_size = sizeof(struct pm8xxx_misc_platform_data); ret = mfd_add_devices(pmic->dev, 0, &misc_cell, 1, NULL, irq_base); if (ret) { pr_err("Failed to add misc subdevice ret=%d\n", ret); goto bail; } } ret = mfd_add_devices(pmic->dev, 0, &thermal_alarm_cell, 1, NULL, irq_base); if (ret) { pr_err("Failed to add thermal alarm subdevice ret=%d\n", ret); goto bail; } ret = mfd_add_devices(pmic->dev, 0, &batt_alarm_cell, 1, NULL, irq_base); if (ret) { pr_err("Failed to add battery alarm subdevice ret=%d\n", ret); goto bail; } if (version != PM8XXX_VERSION_8917) { if (pdata->pwm_pdata) { pwm_cell.platform_data = pdata->pwm_pdata; pwm_cell.pdata_size = sizeof(struct pm8xxx_pwm_platform_data); } ret = mfd_add_devices(pmic->dev, 0, &pwm_cell, 1, NULL, 0); if (ret) { pr_err("Failed to add pwm subdevice ret=%d\n", ret); goto bail; } if (pdata->leds_pdata) { leds_cell.platform_data = pdata->leds_pdata; leds_cell.pdata_size = sizeof(struct pm8xxx_led_platform_data); ret = mfd_add_devices(pmic->dev, 0, &leds_cell, 1, NULL, 0); if (ret) { pr_err("Failed to add leds subdevice ret=%d\n", ret); goto bail; } } if (pdata->vibrator_pdata) { vibrator_cell.platform_data = pdata->vibrator_pdata; vibrator_cell.pdata_size = sizeof(struct pm8xxx_vibrator_platform_data); ret = mfd_add_devices(pmic->dev, 0, &vibrator_cell, 1, NULL, 0); if (ret) { pr_err("Failed to add vibrator ret=%d\n", ret); goto bail; } } } if (pdata->ccadc_pdata) { ccadc_cell.platform_data = pdata->ccadc_pdata; ccadc_cell.pdata_size = sizeof(struct pm8xxx_ccadc_platform_data); ret = mfd_add_devices(pmic->dev, 0, &ccadc_cell, 1, NULL, irq_base); if (ret) { pr_err("Failed to add ccadc subdevice ret=%d\n", ret); goto bail; } } if (pdata->simple_remote_pdata) { simple_remote_cell.platform_data = pdata->simple_remote_pdata; simple_remote_cell.pdata_size = sizeof(struct simple_remote_platform_data); ret = mfd_add_devices(pmic->dev, 0, &simple_remote_cell, 1, NULL, irq_base); if (ret) { pr_err("Failed to add simple remote subdevice" " ret=%d\n", ret); goto bail; } } if (pdata->mic_bias_pdata) { mic_bias_cell.platform_data = pdata->mic_bias_pdata; mic_bias_cell.pdata_size = sizeof(struct pm8921_mic_bias_platform_data); ret = mfd_add_devices(pmic->dev, 0, &mic_bias_cell, 1, NULL, 0); if (ret) { pr_err("Failed to add mic bias subdevice ret=%d\n", ret); goto bail; } } return 0; bail: if (pmic->irq_chip) { pm8xxx_irq_exit(pmic->irq_chip); pmic->irq_chip = NULL; } return ret; }
static int __devinit twl6040_probe(struct platform_device *pdev) { struct twl4030_codec_data *pdata = pdev->dev.platform_data; struct twl6040 *twl6040; struct mfd_cell *cell = NULL; unsigned int naudint; int audpwron; int ret, children = 0; u8 accctl; if(!pdata) { dev_err(&pdev->dev, "Platform data is missing\n"); return -EINVAL; } twl6040 = kzalloc(sizeof(struct twl6040), GFP_KERNEL); if (!twl6040) return -ENOMEM; platform_set_drvdata(pdev, twl6040); twl6040->dev = &pdev->dev; mutex_init(&twl6040->mutex); mutex_init(&twl6040->io_mutex); if (pdata->init) { ret = pdata->init(); if (ret) { dev_err(twl6040->dev, "Platform init failed %d\n", ret); goto init_err; } } twl6040->icrev = twl6040_reg_read(twl6040, TWL6040_REG_ASICREV); if (twl6040->icrev < 0) { ret = twl6040->icrev; goto gpio1_err; } if (pdata && (twl6040_get_icrev(twl6040) > TWL6040_REV_1_0)) audpwron = pdata->audpwron_gpio; else audpwron = -EINVAL; if (pdata) naudint = pdata->naudint_irq; else naudint = 0; twl6040->audpwron = audpwron; twl6040->powered = 0; twl6040->irq = naudint; twl6040->irq_base = pdata->irq_base; init_completion(&twl6040->ready); if (gpio_is_valid(audpwron)) { ret = gpio_request(audpwron, "audpwron"); if (ret) goto gpio1_err; ret = gpio_direction_output(audpwron, 0); if (ret) goto gpio2_err; } if (naudint) { /* codec interrupt */ ret = twl6040_irq_init(twl6040); if (ret) goto gpio2_err; ret = twl6040_request_irq(twl6040, TWL6040_IRQ_READY, twl6040_naudint_handler, "twl6040_irq_ready", twl6040); if (ret) { dev_err(twl6040->dev, "READY IRQ request failed: %d\n", ret); goto irq_err; } } /* dual-access registers controlled by I2C only */ accctl = twl6040_reg_read(twl6040, TWL6040_REG_ACCCTL); twl6040_reg_write(twl6040, TWL6040_REG_ACCCTL, accctl | TWL6040_I2CSEL); if (pdata->get_ext_clk32k) { ret = pdata->get_ext_clk32k(); if (ret) { dev_err(twl6040->dev, "failed to get external 32kHz clock %d\n", ret); goto clk32k_err; } } if (pdata->audio) { cell = &twl6040->cells[children]; cell->name = "twl6040-codec"; cell->platform_data = pdata->audio; cell->pdata_size = sizeof(*pdata->audio); children++; } if (pdata->vibra) { cell = &twl6040->cells[children]; cell->name = "twl6040-vibra"; cell->platform_data = pdata->vibra; cell->pdata_size = sizeof(*pdata->vibra); children++; } if (children) { ret = mfd_add_devices(&pdev->dev, pdev->id, twl6040->cells, children, NULL, 0); if (ret) goto mfd_err; } else { dev_err(&pdev->dev, "No platform data found for children\n"); ret = -ENODEV; goto mfd_err; } return 0; mfd_err: if (pdata->put_ext_clk32k) pdata->put_ext_clk32k(); clk32k_err: if (naudint) twl6040_free_irq(twl6040, TWL6040_IRQ_READY, twl6040); irq_err: if (naudint) twl6040_irq_exit(twl6040); gpio2_err: if (gpio_is_valid(audpwron)) gpio_free(audpwron); gpio1_err: if (pdata->exit) pdata->exit(); init_err: platform_set_drvdata(pdev, NULL); kfree(twl6040); return ret; }