Blame view

drivers/gpio/gpio-tps65910.c 5.16 KB
2537df722   Graeme Gregory   TPS65910: GPIO: A...
1
  /*
c103de240   Grant Likely   gpio: reorganize ...
2
   * TI TPS6591x GPIO driver
2537df722   Graeme Gregory   TPS65910: GPIO: A...
3
4
5
6
   *
   * Copyright 2010 Texas Instruments Inc.
   *
   * Author: Graeme Gregory <gg@slimlogic.co.uk>
02c7a13ea   Paul Gortmaker   gpio: tps65910: m...
7
   * Author: Jorge Eduardo Candelaria <jedu@slimlogic.co.uk>
2537df722   Graeme Gregory   TPS65910: GPIO: A...
8
9
10
11
12
13
14
15
16
   *
   *  This program is free software; you can redistribute it and/or modify it
   *  under  the terms of the GNU General  Public License as published by the
   *  Free Software Foundation;  either version 2 of the License, or (at your
   *  option) any later version.
   *
   */
  
  #include <linux/kernel.h>
02c7a13ea   Paul Gortmaker   gpio: tps65910: m...
17
  #include <linux/init.h>
2537df722   Graeme Gregory   TPS65910: GPIO: A...
18
19
20
  #include <linux/errno.h>
  #include <linux/gpio.h>
  #include <linux/i2c.h>
10bbc48d7   Laxman Dewangan   gpio: Convert tps...
21
  #include <linux/platform_device.h>
2537df722   Graeme Gregory   TPS65910: GPIO: A...
22
  #include <linux/mfd/tps65910.h>
6fe02e9f4   Laxman Dewangan   gpio: tps65910: d...
23
  #include <linux/of_device.h>
2537df722   Graeme Gregory   TPS65910: GPIO: A...
24

10bbc48d7   Laxman Dewangan   gpio: Convert tps...
25
26
27
28
  struct tps65910_gpio {
  	struct gpio_chip gpio_chip;
  	struct tps65910 *tps65910;
  };
2537df722   Graeme Gregory   TPS65910: GPIO: A...
29
30
  static int tps65910_gpio_get(struct gpio_chip *gc, unsigned offset)
  {
b7c17b1b9   Linus Walleij   gpio: tps65910: u...
31
  	struct tps65910_gpio *tps65910_gpio = gpiochip_get_data(gc);
10bbc48d7   Laxman Dewangan   gpio: Convert tps...
32
  	struct tps65910 *tps65910 = tps65910_gpio->tps65910;
3f7e82759   Rhyland Klein   mfd: Commonize tp...
33
  	unsigned int val;
2537df722   Graeme Gregory   TPS65910: GPIO: A...
34

3f7e82759   Rhyland Klein   mfd: Commonize tp...
35
  	tps65910_reg_read(tps65910, TPS65910_GPIO0 + offset, &val);
2537df722   Graeme Gregory   TPS65910: GPIO: A...
36

11ad14f86   Jorge Eduardo Candelaria   TPS65911: Add sup...
37
  	if (val & GPIO_STS_MASK)
2537df722   Graeme Gregory   TPS65910: GPIO: A...
38
39
40
41
42
43
44
45
  		return 1;
  
  	return 0;
  }
  
  static void tps65910_gpio_set(struct gpio_chip *gc, unsigned offset,
  			      int value)
  {
b7c17b1b9   Linus Walleij   gpio: tps65910: u...
46
  	struct tps65910_gpio *tps65910_gpio = gpiochip_get_data(gc);
10bbc48d7   Laxman Dewangan   gpio: Convert tps...
47
  	struct tps65910 *tps65910 = tps65910_gpio->tps65910;
2537df722   Graeme Gregory   TPS65910: GPIO: A...
48
49
  
  	if (value)
3f7e82759   Rhyland Klein   mfd: Commonize tp...
50
  		tps65910_reg_set_bits(tps65910, TPS65910_GPIO0 + offset,
11ad14f86   Jorge Eduardo Candelaria   TPS65911: Add sup...
51
  						GPIO_SET_MASK);
2537df722   Graeme Gregory   TPS65910: GPIO: A...
52
  	else
3f7e82759   Rhyland Klein   mfd: Commonize tp...
53
  		tps65910_reg_clear_bits(tps65910, TPS65910_GPIO0 + offset,
11ad14f86   Jorge Eduardo Candelaria   TPS65911: Add sup...
54
  						GPIO_SET_MASK);
2537df722   Graeme Gregory   TPS65910: GPIO: A...
55
56
57
58
59
  }
  
  static int tps65910_gpio_output(struct gpio_chip *gc, unsigned offset,
  				int value)
  {
b7c17b1b9   Linus Walleij   gpio: tps65910: u...
60
  	struct tps65910_gpio *tps65910_gpio = gpiochip_get_data(gc);
10bbc48d7   Laxman Dewangan   gpio: Convert tps...
61
  	struct tps65910 *tps65910 = tps65910_gpio->tps65910;
2537df722   Graeme Gregory   TPS65910: GPIO: A...
62
63
  
  	/* Set the initial value */
94bd2442d   Laxman Dewangan   gpio: tps65910: U...
64
  	tps65910_gpio_set(gc, offset, value);
2537df722   Graeme Gregory   TPS65910: GPIO: A...
65

3f7e82759   Rhyland Klein   mfd: Commonize tp...
66
  	return tps65910_reg_set_bits(tps65910, TPS65910_GPIO0 + offset,
11ad14f86   Jorge Eduardo Candelaria   TPS65911: Add sup...
67
  						GPIO_CFG_MASK);
2537df722   Graeme Gregory   TPS65910: GPIO: A...
68
69
70
71
  }
  
  static int tps65910_gpio_input(struct gpio_chip *gc, unsigned offset)
  {
b7c17b1b9   Linus Walleij   gpio: tps65910: u...
72
  	struct tps65910_gpio *tps65910_gpio = gpiochip_get_data(gc);
10bbc48d7   Laxman Dewangan   gpio: Convert tps...
73
  	struct tps65910 *tps65910 = tps65910_gpio->tps65910;
2537df722   Graeme Gregory   TPS65910: GPIO: A...
74

3f7e82759   Rhyland Klein   mfd: Commonize tp...
75
  	return tps65910_reg_clear_bits(tps65910, TPS65910_GPIO0 + offset,
11ad14f86   Jorge Eduardo Candelaria   TPS65911: Add sup...
76
  						GPIO_CFG_MASK);
2537df722   Graeme Gregory   TPS65910: GPIO: A...
77
  }
6fe02e9f4   Laxman Dewangan   gpio: tps65910: d...
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
  #ifdef CONFIG_OF
  static struct tps65910_board *tps65910_parse_dt_for_gpio(struct device *dev,
  		struct tps65910 *tps65910, int chip_ngpio)
  {
  	struct tps65910_board *tps65910_board = tps65910->of_plat_data;
  	unsigned int prop_array[TPS6591X_MAX_NUM_GPIO];
  	int ngpio = min(chip_ngpio, TPS6591X_MAX_NUM_GPIO);
  	int ret;
  	int idx;
  
  	tps65910_board->gpio_base = -1;
  	ret = of_property_read_u32_array(tps65910->dev->of_node,
  			"ti,en-gpio-sleep", prop_array, ngpio);
  	if (ret < 0) {
  		dev_dbg(dev, "ti,en-gpio-sleep not specified
  ");
  		return tps65910_board;
  	}
  
  	for (idx = 0; idx < ngpio; idx++)
  		tps65910_board->en_gpio_sleep[idx] = (prop_array[idx] != 0);
  
  	return tps65910_board;
  }
  #else
  static struct tps65910_board *tps65910_parse_dt_for_gpio(struct device *dev,
  		struct tps65910 *tps65910, int chip_ngpio)
  {
  	return NULL;
  }
  #endif
3836309d9   Bill Pemberton   gpio: remove use ...
109
  static int tps65910_gpio_probe(struct platform_device *pdev)
2537df722   Graeme Gregory   TPS65910: GPIO: A...
110
  {
10bbc48d7   Laxman Dewangan   gpio: Convert tps...
111
112
113
  	struct tps65910 *tps65910 = dev_get_drvdata(pdev->dev.parent);
  	struct tps65910_board *pdata = dev_get_platdata(tps65910->dev);
  	struct tps65910_gpio *tps65910_gpio;
2537df722   Graeme Gregory   TPS65910: GPIO: A...
114
  	int ret;
10bbc48d7   Laxman Dewangan   gpio: Convert tps...
115
116
117
118
  	int i;
  
  	tps65910_gpio = devm_kzalloc(&pdev->dev,
  				sizeof(*tps65910_gpio), GFP_KERNEL);
0661175a2   Jingoo Han   gpio: tps65910: r...
119
  	if (!tps65910_gpio)
10bbc48d7   Laxman Dewangan   gpio: Convert tps...
120
  		return -ENOMEM;
2537df722   Graeme Gregory   TPS65910: GPIO: A...
121

10bbc48d7   Laxman Dewangan   gpio: Convert tps...
122
  	tps65910_gpio->tps65910 = tps65910;
2537df722   Graeme Gregory   TPS65910: GPIO: A...
123

10bbc48d7   Laxman Dewangan   gpio: Convert tps...
124
125
  	tps65910_gpio->gpio_chip.owner = THIS_MODULE;
  	tps65910_gpio->gpio_chip.label = tps65910->i2c_client->name;
11ad14f86   Jorge Eduardo Candelaria   TPS65911: Add sup...
126

195c65e83   Laurent Navet   gpio: gpio-tps659...
127
  	switch (tps65910_chip_id(tps65910)) {
11ad14f86   Jorge Eduardo Candelaria   TPS65911: Add sup...
128
  	case TPS65910:
10bbc48d7   Laxman Dewangan   gpio: Convert tps...
129
  		tps65910_gpio->gpio_chip.ngpio = TPS65910_NUM_GPIO;
58956ba23   Axel Lin   gpio: tps65910: a...
130
  		break;
11ad14f86   Jorge Eduardo Candelaria   TPS65911: Add sup...
131
  	case TPS65911:
10bbc48d7   Laxman Dewangan   gpio: Convert tps...
132
  		tps65910_gpio->gpio_chip.ngpio = TPS65911_NUM_GPIO;
58956ba23   Axel Lin   gpio: tps65910: a...
133
  		break;
11ad14f86   Jorge Eduardo Candelaria   TPS65911: Add sup...
134
  	default:
10bbc48d7   Laxman Dewangan   gpio: Convert tps...
135
  		return -EINVAL;
11ad14f86   Jorge Eduardo Candelaria   TPS65911: Add sup...
136
  	}
9fb1f39eb   Linus Walleij   gpio/pinctrl: mak...
137
  	tps65910_gpio->gpio_chip.can_sleep = true;
10bbc48d7   Laxman Dewangan   gpio: Convert tps...
138
139
140
141
  	tps65910_gpio->gpio_chip.direction_input = tps65910_gpio_input;
  	tps65910_gpio->gpio_chip.direction_output = tps65910_gpio_output;
  	tps65910_gpio->gpio_chip.set	= tps65910_gpio_set;
  	tps65910_gpio->gpio_chip.get	= tps65910_gpio_get;
58383c784   Linus Walleij   gpio: change memb...
142
  	tps65910_gpio->gpio_chip.parent = &pdev->dev;
bb39b6551   Jerry Snitselaar   gpio/gpio-tps6591...
143
  #ifdef CONFIG_OF_GPIO
626f9914a   Laxman Dewangan   gpio: tps65910: i...
144
  	tps65910_gpio->gpio_chip.of_node = tps65910->dev->of_node;
bb39b6551   Jerry Snitselaar   gpio/gpio-tps6591...
145
  #endif
10bbc48d7   Laxman Dewangan   gpio: Convert tps...
146
147
148
149
  	if (pdata && pdata->gpio_base)
  		tps65910_gpio->gpio_chip.base = pdata->gpio_base;
  	else
  		tps65910_gpio->gpio_chip.base = -1;
6fe02e9f4   Laxman Dewangan   gpio: tps65910: d...
150
151
152
  	if (!pdata && tps65910->dev->of_node)
  		pdata = tps65910_parse_dt_for_gpio(&pdev->dev, tps65910,
  			tps65910_gpio->gpio_chip.ngpio);
10bbc48d7   Laxman Dewangan   gpio: Convert tps...
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
  	if (!pdata)
  		goto skip_init;
  
  	/* Configure sleep control for gpios if provided */
  	for (i = 0; i < tps65910_gpio->gpio_chip.ngpio; ++i) {
  		if (!pdata->en_gpio_sleep[i])
  			continue;
  
  		ret = tps65910_reg_set_bits(tps65910,
  			TPS65910_GPIO0 + i, GPIO_SLEEP_MASK);
  		if (ret < 0)
  			dev_warn(tps65910->dev,
  				"GPIO Sleep setting failed with err %d
  ", ret);
  	}
  
  skip_init:
bf6e855a4   Laxman Dewangan   gpio: tps65910: U...
170
171
  	ret = devm_gpiochip_add_data(&pdev->dev, &tps65910_gpio->gpio_chip,
  				     tps65910_gpio);
10bbc48d7   Laxman Dewangan   gpio: Convert tps...
172
173
174
175
  	if (ret < 0) {
  		dev_err(&pdev->dev, "Could not register gpiochip, %d
  ", ret);
  		return ret;
9467d298e   Laxman Dewangan   gpio: tps65910: A...
176
  	}
10bbc48d7   Laxman Dewangan   gpio: Convert tps...
177
  	platform_set_drvdata(pdev, tps65910_gpio);
2537df722   Graeme Gregory   TPS65910: GPIO: A...
178

10bbc48d7   Laxman Dewangan   gpio: Convert tps...
179
  	return ret;
2537df722   Graeme Gregory   TPS65910: GPIO: A...
180
  }
10bbc48d7   Laxman Dewangan   gpio: Convert tps...
181

10bbc48d7   Laxman Dewangan   gpio: Convert tps...
182
183
  static struct platform_driver tps65910_gpio_driver = {
  	.driver.name    = "tps65910-gpio",
10bbc48d7   Laxman Dewangan   gpio: Convert tps...
184
  	.probe		= tps65910_gpio_probe,
10bbc48d7   Laxman Dewangan   gpio: Convert tps...
185
186
187
188
189
190
191
  };
  
  static int __init tps65910_gpio_init(void)
  {
  	return platform_driver_register(&tps65910_gpio_driver);
  }
  subsys_initcall(tps65910_gpio_init);