12537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory/*
2c103de240439dfee24ac50eb99c8be3a30d13323Grant Likely * TI TPS6591x GPIO driver
32537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory *
42537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory * Copyright 2010 Texas Instruments Inc.
52537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory *
62537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory * Author: Graeme Gregory <gg@slimlogic.co.uk>
72537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory * Author: Jorge Eduardo Candelaria jedu@slimlogic.co.uk>
82537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory *
92537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory *  This program is free software; you can redistribute it and/or modify it
102537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory *  under  the terms of the GNU General  Public License as published by the
112537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory *  Free Software Foundation;  either version 2 of the License, or (at your
122537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory *  option) any later version.
132537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory *
142537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory */
152537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory
162537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory#include <linux/kernel.h>
172537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory#include <linux/module.h>
182537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory#include <linux/errno.h>
192537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory#include <linux/gpio.h>
202537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory#include <linux/i2c.h>
212537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory#include <linux/mfd/tps65910.h>
222537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory
232537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregorystatic int tps65910_gpio_get(struct gpio_chip *gc, unsigned offset)
242537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory{
252537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory	struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio);
262537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory	uint8_t val;
272537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory
2811ad14f86a7847b084d3e3f114180be39b1c7322Jorge Eduardo Candelaria	tps65910->read(tps65910, TPS65910_GPIO0 + offset, 1, &val);
292537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory
3011ad14f86a7847b084d3e3f114180be39b1c7322Jorge Eduardo Candelaria	if (val & GPIO_STS_MASK)
312537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory		return 1;
322537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory
332537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory	return 0;
342537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory}
352537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory
362537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregorystatic void tps65910_gpio_set(struct gpio_chip *gc, unsigned offset,
372537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory			      int value)
382537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory{
392537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory	struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio);
402537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory
412537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory	if (value)
4211ad14f86a7847b084d3e3f114180be39b1c7322Jorge Eduardo Candelaria		tps65910_set_bits(tps65910, TPS65910_GPIO0 + offset,
4311ad14f86a7847b084d3e3f114180be39b1c7322Jorge Eduardo Candelaria						GPIO_SET_MASK);
442537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory	else
4511ad14f86a7847b084d3e3f114180be39b1c7322Jorge Eduardo Candelaria		tps65910_clear_bits(tps65910, TPS65910_GPIO0 + offset,
4611ad14f86a7847b084d3e3f114180be39b1c7322Jorge Eduardo Candelaria						GPIO_SET_MASK);
472537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory}
482537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory
492537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregorystatic int tps65910_gpio_output(struct gpio_chip *gc, unsigned offset,
502537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory				int value)
512537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory{
522537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory	struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio);
532537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory
542537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory	/* Set the initial value */
5594bd2442d25454a874e070d871f50f4ce9d57101Laxman Dewangan	tps65910_gpio_set(gc, offset, value);
562537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory
5711ad14f86a7847b084d3e3f114180be39b1c7322Jorge Eduardo Candelaria	return tps65910_set_bits(tps65910, TPS65910_GPIO0 + offset,
5811ad14f86a7847b084d3e3f114180be39b1c7322Jorge Eduardo Candelaria						GPIO_CFG_MASK);
592537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory}
602537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory
612537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregorystatic int tps65910_gpio_input(struct gpio_chip *gc, unsigned offset)
622537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory{
632537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory	struct tps65910 *tps65910 = container_of(gc, struct tps65910, gpio);
642537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory
6511ad14f86a7847b084d3e3f114180be39b1c7322Jorge Eduardo Candelaria	return tps65910_clear_bits(tps65910, TPS65910_GPIO0 + offset,
6611ad14f86a7847b084d3e3f114180be39b1c7322Jorge Eduardo Candelaria						GPIO_CFG_MASK);
672537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory}
682537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory
692537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregoryvoid tps65910_gpio_init(struct tps65910 *tps65910, int gpio_base)
702537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory{
712537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory	int ret;
722537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory
732537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory	if (!gpio_base)
742537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory		return;
752537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory
762537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory	tps65910->gpio.owner		= THIS_MODULE;
772537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory	tps65910->gpio.label		= tps65910->i2c_client->name;
782537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory	tps65910->gpio.dev		= tps65910->dev;
792537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory	tps65910->gpio.base		= gpio_base;
8011ad14f86a7847b084d3e3f114180be39b1c7322Jorge Eduardo Candelaria
8111ad14f86a7847b084d3e3f114180be39b1c7322Jorge Eduardo Candelaria	switch(tps65910_chip_id(tps65910)) {
8211ad14f86a7847b084d3e3f114180be39b1c7322Jorge Eduardo Candelaria	case TPS65910:
8311ad14f86a7847b084d3e3f114180be39b1c7322Jorge Eduardo Candelaria		tps65910->gpio.ngpio	= 6;
8458956ba23e2dce83e78cd212cc8305261647684fAxel Lin		break;
8511ad14f86a7847b084d3e3f114180be39b1c7322Jorge Eduardo Candelaria	case TPS65911:
8611ad14f86a7847b084d3e3f114180be39b1c7322Jorge Eduardo Candelaria		tps65910->gpio.ngpio	= 9;
8758956ba23e2dce83e78cd212cc8305261647684fAxel Lin		break;
8811ad14f86a7847b084d3e3f114180be39b1c7322Jorge Eduardo Candelaria	default:
8911ad14f86a7847b084d3e3f114180be39b1c7322Jorge Eduardo Candelaria		return;
9011ad14f86a7847b084d3e3f114180be39b1c7322Jorge Eduardo Candelaria	}
912537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory	tps65910->gpio.can_sleep	= 1;
922537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory
932537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory	tps65910->gpio.direction_input	= tps65910_gpio_input;
942537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory	tps65910->gpio.direction_output	= tps65910_gpio_output;
952537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory	tps65910->gpio.set		= tps65910_gpio_set;
962537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory	tps65910->gpio.get		= tps65910_gpio_get;
972537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory
982537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory	ret = gpiochip_add(&tps65910->gpio);
992537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory
1002537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory	if (ret)
1012537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory		dev_warn(tps65910->dev, "GPIO registration failed: %d\n", ret);
1022537df722d338ab687d7ed91dc589265c0d14aecGraeme Gregory}
103