static int tps65010_probe()

in tps65010.c [523:656]


static int tps65010_probe(struct i2c_client *client,
			  const struct i2c_device_id *id)
{
	struct tps65010		*tps;
	int			status;
	struct tps65010_board	*board = dev_get_platdata(&client->dev);

	if (the_tps) {
		dev_dbg(&client->dev, "only one tps6501x chip allowed\n");
		return -ENODEV;
	}

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
		return -EINVAL;

	tps = devm_kzalloc(&client->dev, sizeof(*tps), GFP_KERNEL);
	if (!tps)
		return -ENOMEM;

	mutex_init(&tps->lock);
	INIT_DELAYED_WORK(&tps->work, tps65010_work);
	tps->client = client;
	tps->model = id->driver_data;

	/* the IRQ is active low, but many gpio lines can't support that
	 * so this driver uses falling-edge triggers instead.
	 */
	if (client->irq > 0) {
		status = request_irq(client->irq, tps65010_irq,
				     IRQF_TRIGGER_FALLING, DRIVER_NAME, tps);
		if (status < 0) {
			dev_dbg(&client->dev, "can't get IRQ %d, err %d\n",
					client->irq, status);
			return status;
		}
		/* annoying race here, ideally we'd have an option
		 * to claim the irq now and enable it later.
		 * FIXME genirq IRQF_NOAUTOEN now solves that ...
		 */
		disable_irq(client->irq);
		set_bit(FLAG_IRQ_ENABLE, &tps->flags);
	} else
		dev_warn(&client->dev, "IRQ not configured!\n");


	switch (tps->model) {
	case TPS65010:
	case TPS65012:
		tps->por = 1;
		break;
	/* else CHGCONFIG.POR is replaced by AUA, enabling a WAIT mode */
	}
	tps->chgconf = i2c_smbus_read_byte_data(client, TPS_CHGCONFIG);
	show_chgconfig(tps->por, "conf/init", tps->chgconf);

	show_chgstatus("chg/init",
		i2c_smbus_read_byte_data(client, TPS_CHGSTATUS));
	show_regstatus("reg/init",
		i2c_smbus_read_byte_data(client, TPS_REGSTATUS));

	pr_debug("%s: vdcdc1 0x%02x, vdcdc2 %02x, vregs1 %02x\n", DRIVER_NAME,
		i2c_smbus_read_byte_data(client, TPS_VDCDC1),
		i2c_smbus_read_byte_data(client, TPS_VDCDC2),
		i2c_smbus_read_byte_data(client, TPS_VREGS1));
	pr_debug("%s: defgpio 0x%02x, mask3 0x%02x\n", DRIVER_NAME,
		i2c_smbus_read_byte_data(client, TPS_DEFGPIO),
		i2c_smbus_read_byte_data(client, TPS_MASK3));

	i2c_set_clientdata(client, tps);
	the_tps = tps;

#if	defined(CONFIG_USB_GADGET) && !defined(CONFIG_USB_OTG)
	/* USB hosts can't draw VBUS.  OTG devices could, later
	 * when OTG infrastructure enables it.  USB peripherals
	 * could be relying on VBUS while booting, though.
	 */
	tps->vbus = 100;
#endif

	/* unmask the "interesting" irqs, then poll once to
	 * kickstart monitoring, initialize shadowed status
	 * registers, and maybe disable VBUS draw.
	 */
	tps->nmask1 = ~0;
	(void) i2c_smbus_write_byte_data(client, TPS_MASK1, ~tps->nmask1);

	tps->nmask2 = TPS_REG_ONOFF;
	if (tps->model == TPS65013)
		tps->nmask2 |= TPS_REG_NO_CHG;
	(void) i2c_smbus_write_byte_data(client, TPS_MASK2, ~tps->nmask2);

	(void) i2c_smbus_write_byte_data(client, TPS_MASK3, 0x0f
		| i2c_smbus_read_byte_data(client, TPS_MASK3));

	tps65010_work(&tps->work.work);

	tps->file = debugfs_create_file(DRIVER_NAME, S_IRUGO, NULL,
				tps, DEBUG_FOPS);

	/* optionally register GPIOs */
	if (board && board->base != 0) {
		tps->outmask = board->outmask;

		tps->chip.label = client->name;
		tps->chip.parent = &client->dev;
		tps->chip.owner = THIS_MODULE;

		tps->chip.set = tps65010_gpio_set;
		tps->chip.direction_output = tps65010_output;

		/* NOTE:  only partial support for inputs; nyet IRQs */
		tps->chip.get = tps65010_gpio_get;

		tps->chip.base = board->base;
		tps->chip.ngpio = 7;
		tps->chip.can_sleep = 1;

		status = gpiochip_add_data(&tps->chip, tps);
		if (status < 0)
			dev_err(&client->dev, "can't add gpiochip, err %d\n",
					status);
		else if (board->setup) {
			status = board->setup(client, board->context);
			if (status < 0) {
				dev_dbg(&client->dev,
					"board %s %s err %d\n",
					"setup", client->name, status);
				status = 0;
			}
		}
	}

	return 0;
}