Esempio n. 1
0
static int max77804k_i2c_probe(struct i2c_client *i2c,
			      const struct i2c_device_id *id)
{
	struct max77804k_dev *max77804k;
	struct max77804k_platform_data *pdata;
	u8 reg_data;
	int ret = 0;
	dev_info(&i2c->dev, "%s\n", __func__);

	max77804k = kzalloc(sizeof(struct max77804k_dev), GFP_KERNEL);
	if (max77804k == NULL)
		return -ENOMEM;

	if (i2c->dev.of_node) {
		pdata = devm_kzalloc(&i2c->dev,
				sizeof(struct max77804k_platform_data),
				GFP_KERNEL);
		if (!pdata) {
			dev_err(&i2c->dev, "Failed to allocate memory \n");
			ret = -ENOMEM;
			goto err;
		}

		ret = of_max77804k_dt(&i2c->dev, pdata);
		if (ret < 0){
			dev_err(&i2c->dev, "Failed to get device of_node \n");
			return ret;
		}
		/*Filling the platform data*/
		pdata->muic_data = &max77804k_muic;
#ifdef CONFIG_REGULATOR_MAX77804K
		pdata->num_regulators = MAX77804K_REG_MAX;
		pdata->regulators = max77804k_regulators;
#endif
#ifdef CONFIG_LEDS_MAX77804K
		pdata->led_data = &max77804k_led_pdata;
#endif
		/*pdata update to other modules*/
		i2c->dev.platform_data = pdata;
	} else
		pdata = i2c->dev.platform_data;

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

	max77804k->i2c = i2c;
	max77804k->irq = i2c->irq;
	if (pdata) {
		max77804k->irq_base = pdata->irq_base;
		max77804k->irq_gpio = pdata->irq_gpio;
		max77804k->wakeup = pdata->wakeup;
		gpio_tlmm_config(GPIO_CFG(max77804k->irq_gpio,  0, GPIO_CFG_INPUT,
                GPIO_CFG_NO_PULL, GPIO_CFG_2MA), GPIO_CFG_DISABLE);
	} else {
		ret = -EINVAL;
		goto err;
	}

	mutex_init(&max77804k->iolock);

	if (max77804k_read_reg(i2c, MAX77804K_PMIC_REG_PMIC_ID2, &reg_data) < 0) {
		dev_err(max77804k->dev,
			"device not found on this channel (this is not an error)\n");
		ret = -ENODEV;
		goto err;
	} else {
		/* print rev */
		max77804k->pmic_rev = (reg_data & 0x7);
		max77804k->pmic_ver = ((reg_data & 0xF8) >> 0x3);
		pr_info("%s: device found: rev.0x%x, ver.0x%x\n", __func__,
				max77804k->pmic_rev, max77804k->pmic_ver);
	}
	max77804k_update_reg(i2c, MAX77804K_CHG_REG_SAFEOUT_CTRL, 0x00, 0x30);

	max77804k->muic = i2c_new_dummy(i2c->adapter, I2C_ADDR_MUIC);
	i2c_set_clientdata(max77804k->muic, max77804k);

	max77804k->haptic = i2c_new_dummy(i2c->adapter, I2C_ADDR_HAPTIC);
	i2c_set_clientdata(max77804k->haptic, max77804k);

	ret = max77804k_irq_init(max77804k);
	if (ret < 0)
		goto err_irq_init;

	ret = mfd_add_devices(max77804k->dev, -1, max77804k_devs,
			ARRAY_SIZE(max77804k_devs), NULL, 0);
	if (ret < 0)
		goto err_mfd;

	device_init_wakeup(max77804k->dev, pdata->wakeup);

	return ret;

err_mfd:
	mfd_remove_devices(max77804k->dev);
	max77804k_irq_exit(max77804k);
err_irq_init:
	i2c_unregister_device(max77804k->muic);
	i2c_unregister_device(max77804k->haptic);
err:
	kfree(max77804k);
	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");
            goto err;
        }

        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->irqf_trigger = pdata->irqf_trigger;
        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_w_lock;
    } 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_w_lock:
    mutex_destroy(&max77804->i2c_lock);
err:
    kfree(max77804);
    return ret;
}