Esempio n. 1
0
static int __devinit tc3589x_probe(struct i2c_client *i2c,
				   const struct i2c_device_id *id)
{
	struct tc3589x_platform_data *pdata = i2c->dev.platform_data;
	struct tc3589x *tc3589x;
	int ret;

	if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA
				     | I2C_FUNC_SMBUS_I2C_BLOCK))
		return -EIO;

	tc3589x = kzalloc(sizeof(struct tc3589x), GFP_KERNEL);
	if (!tc3589x)
		return -ENOMEM;

	mutex_init(&tc3589x->lock);

	tc3589x->dev = &i2c->dev;
	tc3589x->i2c = i2c;
	tc3589x->pdata = pdata;
	tc3589x->irq_base = pdata->irq_base;
	tc3589x->num_gpio = id->driver_data;

	i2c_set_clientdata(i2c, tc3589x);

	ret = tc3589x_chip_init(tc3589x);
	if (ret)
		goto out_free;

	ret = tc3589x_irq_init(tc3589x);
	if (ret)
		goto out_free;

	ret = request_threaded_irq(tc3589x->i2c->irq, NULL, tc3589x_irq,
				   IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
				   "tc3589x", tc3589x);
	if (ret) {
		dev_err(tc3589x->dev, "failed to request IRQ: %d\n", ret);
		goto out_removeirq;
	}

	ret = tc3589x_device_init(tc3589x);
	if (ret) {
		dev_err(tc3589x->dev, "failed to add child devices\n");
		goto out_freeirq;
	}

	return 0;

out_freeirq:
	free_irq(tc3589x->i2c->irq, tc3589x);
out_removeirq:
	tc3589x_irq_remove(tc3589x);
out_free:
	kfree(tc3589x);
	return ret;
}
Esempio n. 2
0
static int tc3589x_probe(struct i2c_client *i2c,
				   const struct i2c_device_id *id)
{
	struct device_node *np = i2c->dev.of_node;
	struct tc3589x_platform_data *pdata = dev_get_platdata(&i2c->dev);
	struct tc3589x *tc3589x;
	enum tc3589x_version version;
	int ret;

	if (!pdata) {
		pdata = tc3589x_of_probe(&i2c->dev, &version);
		if (IS_ERR(pdata)) {
			dev_err(&i2c->dev, "No platform data or DT found\n");
			return PTR_ERR(pdata);
		}
	} else {
		/* When not probing from device tree we have this ID */
		version = id->driver_data;
	}

	if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA
				     | I2C_FUNC_SMBUS_I2C_BLOCK))
		return -EIO;

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

	mutex_init(&tc3589x->lock);

	tc3589x->dev = &i2c->dev;
	tc3589x->i2c = i2c;
	tc3589x->pdata = pdata;
	tc3589x->irq_base = pdata->irq_base;

	switch (version) {
	case TC3589X_TC35893:
	case TC3589X_TC35895:
	case TC3589X_TC35896:
		tc3589x->num_gpio = 20;
		break;
	case TC3589X_TC35890:
	case TC3589X_TC35892:
	case TC3589X_TC35894:
	case TC3589X_UNKNOWN:
	default:
		tc3589x->num_gpio = 24;
		break;
	}

	i2c_set_clientdata(i2c, tc3589x);

	ret = tc3589x_chip_init(tc3589x);
	if (ret)
		return ret;

	ret = tc3589x_irq_init(tc3589x, np);
	if (ret)
		return ret;

	ret = request_threaded_irq(tc3589x->i2c->irq, NULL, tc3589x_irq,
				   IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
				   "tc3589x", tc3589x);
	if (ret) {
		dev_err(tc3589x->dev, "failed to request IRQ: %d\n", ret);
		return ret;
	}

	ret = tc3589x_device_init(tc3589x);
	if (ret) {
		dev_err(tc3589x->dev, "failed to add child devices\n");
		return ret;
	}

	return 0;
}