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;
}
Ejemplo n.º 2
0
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, &reg);
	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;
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
0
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(&regulator_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(&regulator_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;
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 9
0
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;
}
Ejemplo n.º 10
0
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, &reg_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;
}
Ejemplo n.º 11
0
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;
}
Ejemplo n.º 12
0
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;
}
Ejemplo n.º 13
0
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;
}
Ejemplo n.º 14
0
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, &reg_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;
}
Ejemplo n.º 15
0
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;
}
Ejemplo n.º 16
0
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;
}
Ejemplo n.º 17
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;
}
Ejemplo n.º 18
0
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;
}
Ejemplo n.º 19
0
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;
}
Ejemplo n.º 20
0
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, &reg_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, &reg_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;
}
Ejemplo n.º 23
0
/*
 * 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;
}
Ejemplo n.º 24
0
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, &reg);
    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;
}