1*4882a593Smuzhiyun // SPDX-License-Identifier: GPL-2.0
2*4882a593Smuzhiyun /*
3*4882a593Smuzhiyun * Intel Whiskey Cove PMIC GPIO Driver
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * This driver is written based on gpio-crystalcove.c
6*4882a593Smuzhiyun *
7*4882a593Smuzhiyun * Copyright (C) 2016 Intel Corporation. All rights reserved.
8*4882a593Smuzhiyun */
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #include <linux/bitops.h>
11*4882a593Smuzhiyun #include <linux/gpio/driver.h>
12*4882a593Smuzhiyun #include <linux/interrupt.h>
13*4882a593Smuzhiyun #include <linux/mfd/intel_soc_pmic.h>
14*4882a593Smuzhiyun #include <linux/module.h>
15*4882a593Smuzhiyun #include <linux/platform_device.h>
16*4882a593Smuzhiyun #include <linux/regmap.h>
17*4882a593Smuzhiyun #include <linux/seq_file.h>
18*4882a593Smuzhiyun
19*4882a593Smuzhiyun /*
20*4882a593Smuzhiyun * Whiskey Cove PMIC has 13 physical GPIO pins divided into 3 banks:
21*4882a593Smuzhiyun * Bank 0: Pin 0 - 6
22*4882a593Smuzhiyun * Bank 1: Pin 7 - 10
23*4882a593Smuzhiyun * Bank 2: Pin 11 - 12
24*4882a593Smuzhiyun * Each pin has one output control register and one input control register.
25*4882a593Smuzhiyun */
26*4882a593Smuzhiyun #define BANK0_NR_PINS 7
27*4882a593Smuzhiyun #define BANK1_NR_PINS 4
28*4882a593Smuzhiyun #define BANK2_NR_PINS 2
29*4882a593Smuzhiyun #define WCOVE_GPIO_NUM (BANK0_NR_PINS + BANK1_NR_PINS + BANK2_NR_PINS)
30*4882a593Smuzhiyun #define WCOVE_VGPIO_NUM 94
31*4882a593Smuzhiyun /* GPIO output control registers (one per pin): 0x4e44 - 0x4e50 */
32*4882a593Smuzhiyun #define GPIO_OUT_CTRL_BASE 0x4e44
33*4882a593Smuzhiyun /* GPIO input control registers (one per pin): 0x4e51 - 0x4e5d */
34*4882a593Smuzhiyun #define GPIO_IN_CTRL_BASE 0x4e51
35*4882a593Smuzhiyun
36*4882a593Smuzhiyun /*
37*4882a593Smuzhiyun * GPIO interrupts are organized in two groups:
38*4882a593Smuzhiyun * Group 0: Bank 0 pins (Pin 0 - 6)
39*4882a593Smuzhiyun * Group 1: Bank 1 and Bank 2 pins (Pin 7 - 12)
40*4882a593Smuzhiyun * Each group has two registers (one bit per pin): status and mask.
41*4882a593Smuzhiyun */
42*4882a593Smuzhiyun #define GROUP0_NR_IRQS 7
43*4882a593Smuzhiyun #define GROUP1_NR_IRQS 6
44*4882a593Smuzhiyun #define IRQ_MASK_BASE 0x4e19
45*4882a593Smuzhiyun #define IRQ_STATUS_BASE 0x4e0b
46*4882a593Smuzhiyun #define GPIO_IRQ0_MASK GENMASK(6, 0)
47*4882a593Smuzhiyun #define GPIO_IRQ1_MASK GENMASK(5, 0)
48*4882a593Smuzhiyun #define UPDATE_IRQ_TYPE BIT(0)
49*4882a593Smuzhiyun #define UPDATE_IRQ_MASK BIT(1)
50*4882a593Smuzhiyun
51*4882a593Smuzhiyun #define CTLI_INTCNT_DIS (0 << 1)
52*4882a593Smuzhiyun #define CTLI_INTCNT_NE (1 << 1)
53*4882a593Smuzhiyun #define CTLI_INTCNT_PE (2 << 1)
54*4882a593Smuzhiyun #define CTLI_INTCNT_BE (3 << 1)
55*4882a593Smuzhiyun
56*4882a593Smuzhiyun #define CTLO_DIR_IN (0 << 5)
57*4882a593Smuzhiyun #define CTLO_DIR_OUT (1 << 5)
58*4882a593Smuzhiyun
59*4882a593Smuzhiyun #define CTLO_DRV_MASK (1 << 4)
60*4882a593Smuzhiyun #define CTLO_DRV_OD (0 << 4)
61*4882a593Smuzhiyun #define CTLO_DRV_CMOS (1 << 4)
62*4882a593Smuzhiyun
63*4882a593Smuzhiyun #define CTLO_DRV_REN (1 << 3)
64*4882a593Smuzhiyun
65*4882a593Smuzhiyun #define CTLO_RVAL_2KDOWN (0 << 1)
66*4882a593Smuzhiyun #define CTLO_RVAL_2KUP (1 << 1)
67*4882a593Smuzhiyun #define CTLO_RVAL_50KDOWN (2 << 1)
68*4882a593Smuzhiyun #define CTLO_RVAL_50KUP (3 << 1)
69*4882a593Smuzhiyun
70*4882a593Smuzhiyun #define CTLO_INPUT_SET (CTLO_DRV_CMOS | CTLO_DRV_REN | CTLO_RVAL_2KUP)
71*4882a593Smuzhiyun #define CTLO_OUTPUT_SET (CTLO_DIR_OUT | CTLO_INPUT_SET)
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun enum ctrl_register {
74*4882a593Smuzhiyun CTRL_IN,
75*4882a593Smuzhiyun CTRL_OUT,
76*4882a593Smuzhiyun };
77*4882a593Smuzhiyun
78*4882a593Smuzhiyun /*
79*4882a593Smuzhiyun * struct wcove_gpio - Whiskey Cove GPIO controller
80*4882a593Smuzhiyun * @buslock: for bus lock/sync and unlock.
81*4882a593Smuzhiyun * @chip: the abstract gpio_chip structure.
82*4882a593Smuzhiyun * @dev: the gpio device
83*4882a593Smuzhiyun * @regmap: the regmap from the parent device.
84*4882a593Smuzhiyun * @regmap_irq_chip: the regmap of the gpio irq chip.
85*4882a593Smuzhiyun * @update: pending IRQ setting update, to be written to the chip upon unlock.
86*4882a593Smuzhiyun * @intcnt: the Interrupt Detect value to be written.
87*4882a593Smuzhiyun * @set_irq_mask: true if the IRQ mask needs to be set, false to clear.
88*4882a593Smuzhiyun */
89*4882a593Smuzhiyun struct wcove_gpio {
90*4882a593Smuzhiyun struct mutex buslock;
91*4882a593Smuzhiyun struct gpio_chip chip;
92*4882a593Smuzhiyun struct device *dev;
93*4882a593Smuzhiyun struct regmap *regmap;
94*4882a593Smuzhiyun struct regmap_irq_chip_data *regmap_irq_chip;
95*4882a593Smuzhiyun int update;
96*4882a593Smuzhiyun int intcnt;
97*4882a593Smuzhiyun bool set_irq_mask;
98*4882a593Smuzhiyun };
99*4882a593Smuzhiyun
to_reg(int gpio,enum ctrl_register reg_type)100*4882a593Smuzhiyun static inline int to_reg(int gpio, enum ctrl_register reg_type)
101*4882a593Smuzhiyun {
102*4882a593Smuzhiyun unsigned int reg;
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun if (gpio >= WCOVE_GPIO_NUM)
105*4882a593Smuzhiyun return -EOPNOTSUPP;
106*4882a593Smuzhiyun
107*4882a593Smuzhiyun if (reg_type == CTRL_IN)
108*4882a593Smuzhiyun reg = GPIO_IN_CTRL_BASE + gpio;
109*4882a593Smuzhiyun else
110*4882a593Smuzhiyun reg = GPIO_OUT_CTRL_BASE + gpio;
111*4882a593Smuzhiyun
112*4882a593Smuzhiyun return reg;
113*4882a593Smuzhiyun }
114*4882a593Smuzhiyun
wcove_update_irq_mask(struct wcove_gpio * wg,int gpio)115*4882a593Smuzhiyun static void wcove_update_irq_mask(struct wcove_gpio *wg, int gpio)
116*4882a593Smuzhiyun {
117*4882a593Smuzhiyun unsigned int reg, mask;
118*4882a593Smuzhiyun
119*4882a593Smuzhiyun if (gpio < GROUP0_NR_IRQS) {
120*4882a593Smuzhiyun reg = IRQ_MASK_BASE;
121*4882a593Smuzhiyun mask = BIT(gpio % GROUP0_NR_IRQS);
122*4882a593Smuzhiyun } else {
123*4882a593Smuzhiyun reg = IRQ_MASK_BASE + 1;
124*4882a593Smuzhiyun mask = BIT((gpio - GROUP0_NR_IRQS) % GROUP1_NR_IRQS);
125*4882a593Smuzhiyun }
126*4882a593Smuzhiyun
127*4882a593Smuzhiyun if (wg->set_irq_mask)
128*4882a593Smuzhiyun regmap_update_bits(wg->regmap, reg, mask, mask);
129*4882a593Smuzhiyun else
130*4882a593Smuzhiyun regmap_update_bits(wg->regmap, reg, mask, 0);
131*4882a593Smuzhiyun }
132*4882a593Smuzhiyun
wcove_update_irq_ctrl(struct wcove_gpio * wg,int gpio)133*4882a593Smuzhiyun static void wcove_update_irq_ctrl(struct wcove_gpio *wg, int gpio)
134*4882a593Smuzhiyun {
135*4882a593Smuzhiyun int reg = to_reg(gpio, CTRL_IN);
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun if (reg < 0)
138*4882a593Smuzhiyun return;
139*4882a593Smuzhiyun
140*4882a593Smuzhiyun regmap_update_bits(wg->regmap, reg, CTLI_INTCNT_BE, wg->intcnt);
141*4882a593Smuzhiyun }
142*4882a593Smuzhiyun
wcove_gpio_dir_in(struct gpio_chip * chip,unsigned int gpio)143*4882a593Smuzhiyun static int wcove_gpio_dir_in(struct gpio_chip *chip, unsigned int gpio)
144*4882a593Smuzhiyun {
145*4882a593Smuzhiyun struct wcove_gpio *wg = gpiochip_get_data(chip);
146*4882a593Smuzhiyun int reg = to_reg(gpio, CTRL_OUT);
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun if (reg < 0)
149*4882a593Smuzhiyun return 0;
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun return regmap_write(wg->regmap, reg, CTLO_INPUT_SET);
152*4882a593Smuzhiyun }
153*4882a593Smuzhiyun
wcove_gpio_dir_out(struct gpio_chip * chip,unsigned int gpio,int value)154*4882a593Smuzhiyun static int wcove_gpio_dir_out(struct gpio_chip *chip, unsigned int gpio,
155*4882a593Smuzhiyun int value)
156*4882a593Smuzhiyun {
157*4882a593Smuzhiyun struct wcove_gpio *wg = gpiochip_get_data(chip);
158*4882a593Smuzhiyun int reg = to_reg(gpio, CTRL_OUT);
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun if (reg < 0)
161*4882a593Smuzhiyun return 0;
162*4882a593Smuzhiyun
163*4882a593Smuzhiyun return regmap_write(wg->regmap, reg, CTLO_OUTPUT_SET | value);
164*4882a593Smuzhiyun }
165*4882a593Smuzhiyun
wcove_gpio_get_direction(struct gpio_chip * chip,unsigned int gpio)166*4882a593Smuzhiyun static int wcove_gpio_get_direction(struct gpio_chip *chip, unsigned int gpio)
167*4882a593Smuzhiyun {
168*4882a593Smuzhiyun struct wcove_gpio *wg = gpiochip_get_data(chip);
169*4882a593Smuzhiyun unsigned int val;
170*4882a593Smuzhiyun int ret, reg = to_reg(gpio, CTRL_OUT);
171*4882a593Smuzhiyun
172*4882a593Smuzhiyun if (reg < 0)
173*4882a593Smuzhiyun return GPIO_LINE_DIRECTION_OUT;
174*4882a593Smuzhiyun
175*4882a593Smuzhiyun ret = regmap_read(wg->regmap, reg, &val);
176*4882a593Smuzhiyun if (ret)
177*4882a593Smuzhiyun return ret;
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun if (val & CTLO_DIR_OUT)
180*4882a593Smuzhiyun return GPIO_LINE_DIRECTION_OUT;
181*4882a593Smuzhiyun
182*4882a593Smuzhiyun return GPIO_LINE_DIRECTION_IN;
183*4882a593Smuzhiyun }
184*4882a593Smuzhiyun
wcove_gpio_get(struct gpio_chip * chip,unsigned int gpio)185*4882a593Smuzhiyun static int wcove_gpio_get(struct gpio_chip *chip, unsigned int gpio)
186*4882a593Smuzhiyun {
187*4882a593Smuzhiyun struct wcove_gpio *wg = gpiochip_get_data(chip);
188*4882a593Smuzhiyun unsigned int val;
189*4882a593Smuzhiyun int ret, reg = to_reg(gpio, CTRL_IN);
190*4882a593Smuzhiyun
191*4882a593Smuzhiyun if (reg < 0)
192*4882a593Smuzhiyun return 0;
193*4882a593Smuzhiyun
194*4882a593Smuzhiyun ret = regmap_read(wg->regmap, reg, &val);
195*4882a593Smuzhiyun if (ret)
196*4882a593Smuzhiyun return ret;
197*4882a593Smuzhiyun
198*4882a593Smuzhiyun return val & 0x1;
199*4882a593Smuzhiyun }
200*4882a593Smuzhiyun
wcove_gpio_set(struct gpio_chip * chip,unsigned int gpio,int value)201*4882a593Smuzhiyun static void wcove_gpio_set(struct gpio_chip *chip, unsigned int gpio, int value)
202*4882a593Smuzhiyun {
203*4882a593Smuzhiyun struct wcove_gpio *wg = gpiochip_get_data(chip);
204*4882a593Smuzhiyun int reg = to_reg(gpio, CTRL_OUT);
205*4882a593Smuzhiyun
206*4882a593Smuzhiyun if (reg < 0)
207*4882a593Smuzhiyun return;
208*4882a593Smuzhiyun
209*4882a593Smuzhiyun if (value)
210*4882a593Smuzhiyun regmap_update_bits(wg->regmap, reg, 1, 1);
211*4882a593Smuzhiyun else
212*4882a593Smuzhiyun regmap_update_bits(wg->regmap, reg, 1, 0);
213*4882a593Smuzhiyun }
214*4882a593Smuzhiyun
wcove_gpio_set_config(struct gpio_chip * chip,unsigned int gpio,unsigned long config)215*4882a593Smuzhiyun static int wcove_gpio_set_config(struct gpio_chip *chip, unsigned int gpio,
216*4882a593Smuzhiyun unsigned long config)
217*4882a593Smuzhiyun {
218*4882a593Smuzhiyun struct wcove_gpio *wg = gpiochip_get_data(chip);
219*4882a593Smuzhiyun int reg = to_reg(gpio, CTRL_OUT);
220*4882a593Smuzhiyun
221*4882a593Smuzhiyun if (reg < 0)
222*4882a593Smuzhiyun return 0;
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun switch (pinconf_to_config_param(config)) {
225*4882a593Smuzhiyun case PIN_CONFIG_DRIVE_OPEN_DRAIN:
226*4882a593Smuzhiyun return regmap_update_bits(wg->regmap, reg, CTLO_DRV_MASK,
227*4882a593Smuzhiyun CTLO_DRV_OD);
228*4882a593Smuzhiyun case PIN_CONFIG_DRIVE_PUSH_PULL:
229*4882a593Smuzhiyun return regmap_update_bits(wg->regmap, reg, CTLO_DRV_MASK,
230*4882a593Smuzhiyun CTLO_DRV_CMOS);
231*4882a593Smuzhiyun default:
232*4882a593Smuzhiyun break;
233*4882a593Smuzhiyun }
234*4882a593Smuzhiyun
235*4882a593Smuzhiyun return -ENOTSUPP;
236*4882a593Smuzhiyun }
237*4882a593Smuzhiyun
wcove_irq_type(struct irq_data * data,unsigned int type)238*4882a593Smuzhiyun static int wcove_irq_type(struct irq_data *data, unsigned int type)
239*4882a593Smuzhiyun {
240*4882a593Smuzhiyun struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
241*4882a593Smuzhiyun struct wcove_gpio *wg = gpiochip_get_data(chip);
242*4882a593Smuzhiyun
243*4882a593Smuzhiyun if (data->hwirq >= WCOVE_GPIO_NUM)
244*4882a593Smuzhiyun return 0;
245*4882a593Smuzhiyun
246*4882a593Smuzhiyun switch (type) {
247*4882a593Smuzhiyun case IRQ_TYPE_NONE:
248*4882a593Smuzhiyun wg->intcnt = CTLI_INTCNT_DIS;
249*4882a593Smuzhiyun break;
250*4882a593Smuzhiyun case IRQ_TYPE_EDGE_BOTH:
251*4882a593Smuzhiyun wg->intcnt = CTLI_INTCNT_BE;
252*4882a593Smuzhiyun break;
253*4882a593Smuzhiyun case IRQ_TYPE_EDGE_RISING:
254*4882a593Smuzhiyun wg->intcnt = CTLI_INTCNT_PE;
255*4882a593Smuzhiyun break;
256*4882a593Smuzhiyun case IRQ_TYPE_EDGE_FALLING:
257*4882a593Smuzhiyun wg->intcnt = CTLI_INTCNT_NE;
258*4882a593Smuzhiyun break;
259*4882a593Smuzhiyun default:
260*4882a593Smuzhiyun return -EINVAL;
261*4882a593Smuzhiyun }
262*4882a593Smuzhiyun
263*4882a593Smuzhiyun wg->update |= UPDATE_IRQ_TYPE;
264*4882a593Smuzhiyun
265*4882a593Smuzhiyun return 0;
266*4882a593Smuzhiyun }
267*4882a593Smuzhiyun
wcove_bus_lock(struct irq_data * data)268*4882a593Smuzhiyun static void wcove_bus_lock(struct irq_data *data)
269*4882a593Smuzhiyun {
270*4882a593Smuzhiyun struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
271*4882a593Smuzhiyun struct wcove_gpio *wg = gpiochip_get_data(chip);
272*4882a593Smuzhiyun
273*4882a593Smuzhiyun mutex_lock(&wg->buslock);
274*4882a593Smuzhiyun }
275*4882a593Smuzhiyun
wcove_bus_sync_unlock(struct irq_data * data)276*4882a593Smuzhiyun static void wcove_bus_sync_unlock(struct irq_data *data)
277*4882a593Smuzhiyun {
278*4882a593Smuzhiyun struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
279*4882a593Smuzhiyun struct wcove_gpio *wg = gpiochip_get_data(chip);
280*4882a593Smuzhiyun int gpio = data->hwirq;
281*4882a593Smuzhiyun
282*4882a593Smuzhiyun if (wg->update & UPDATE_IRQ_TYPE)
283*4882a593Smuzhiyun wcove_update_irq_ctrl(wg, gpio);
284*4882a593Smuzhiyun if (wg->update & UPDATE_IRQ_MASK)
285*4882a593Smuzhiyun wcove_update_irq_mask(wg, gpio);
286*4882a593Smuzhiyun wg->update = 0;
287*4882a593Smuzhiyun
288*4882a593Smuzhiyun mutex_unlock(&wg->buslock);
289*4882a593Smuzhiyun }
290*4882a593Smuzhiyun
wcove_irq_unmask(struct irq_data * data)291*4882a593Smuzhiyun static void wcove_irq_unmask(struct irq_data *data)
292*4882a593Smuzhiyun {
293*4882a593Smuzhiyun struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
294*4882a593Smuzhiyun struct wcove_gpio *wg = gpiochip_get_data(chip);
295*4882a593Smuzhiyun
296*4882a593Smuzhiyun if (data->hwirq >= WCOVE_GPIO_NUM)
297*4882a593Smuzhiyun return;
298*4882a593Smuzhiyun
299*4882a593Smuzhiyun wg->set_irq_mask = false;
300*4882a593Smuzhiyun wg->update |= UPDATE_IRQ_MASK;
301*4882a593Smuzhiyun }
302*4882a593Smuzhiyun
wcove_irq_mask(struct irq_data * data)303*4882a593Smuzhiyun static void wcove_irq_mask(struct irq_data *data)
304*4882a593Smuzhiyun {
305*4882a593Smuzhiyun struct gpio_chip *chip = irq_data_get_irq_chip_data(data);
306*4882a593Smuzhiyun struct wcove_gpio *wg = gpiochip_get_data(chip);
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun if (data->hwirq >= WCOVE_GPIO_NUM)
309*4882a593Smuzhiyun return;
310*4882a593Smuzhiyun
311*4882a593Smuzhiyun wg->set_irq_mask = true;
312*4882a593Smuzhiyun wg->update |= UPDATE_IRQ_MASK;
313*4882a593Smuzhiyun }
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun static struct irq_chip wcove_irqchip = {
316*4882a593Smuzhiyun .name = "Whiskey Cove",
317*4882a593Smuzhiyun .irq_mask = wcove_irq_mask,
318*4882a593Smuzhiyun .irq_unmask = wcove_irq_unmask,
319*4882a593Smuzhiyun .irq_set_type = wcove_irq_type,
320*4882a593Smuzhiyun .irq_bus_lock = wcove_bus_lock,
321*4882a593Smuzhiyun .irq_bus_sync_unlock = wcove_bus_sync_unlock,
322*4882a593Smuzhiyun };
323*4882a593Smuzhiyun
wcove_gpio_irq_handler(int irq,void * data)324*4882a593Smuzhiyun static irqreturn_t wcove_gpio_irq_handler(int irq, void *data)
325*4882a593Smuzhiyun {
326*4882a593Smuzhiyun struct wcove_gpio *wg = (struct wcove_gpio *)data;
327*4882a593Smuzhiyun unsigned int pending, virq, gpio, mask, offset;
328*4882a593Smuzhiyun u8 p[2];
329*4882a593Smuzhiyun
330*4882a593Smuzhiyun if (regmap_bulk_read(wg->regmap, IRQ_STATUS_BASE, p, 2)) {
331*4882a593Smuzhiyun dev_err(wg->dev, "Failed to read irq status register\n");
332*4882a593Smuzhiyun return IRQ_NONE;
333*4882a593Smuzhiyun }
334*4882a593Smuzhiyun
335*4882a593Smuzhiyun pending = (p[0] & GPIO_IRQ0_MASK) | ((p[1] & GPIO_IRQ1_MASK) << 7);
336*4882a593Smuzhiyun if (!pending)
337*4882a593Smuzhiyun return IRQ_NONE;
338*4882a593Smuzhiyun
339*4882a593Smuzhiyun /* Iterate until no interrupt is pending */
340*4882a593Smuzhiyun while (pending) {
341*4882a593Smuzhiyun /* One iteration is for all pending bits */
342*4882a593Smuzhiyun for_each_set_bit(gpio, (const unsigned long *)&pending,
343*4882a593Smuzhiyun WCOVE_GPIO_NUM) {
344*4882a593Smuzhiyun offset = (gpio > GROUP0_NR_IRQS) ? 1 : 0;
345*4882a593Smuzhiyun mask = (offset == 1) ? BIT(gpio - GROUP0_NR_IRQS) :
346*4882a593Smuzhiyun BIT(gpio);
347*4882a593Smuzhiyun virq = irq_find_mapping(wg->chip.irq.domain, gpio);
348*4882a593Smuzhiyun handle_nested_irq(virq);
349*4882a593Smuzhiyun regmap_update_bits(wg->regmap, IRQ_STATUS_BASE + offset,
350*4882a593Smuzhiyun mask, mask);
351*4882a593Smuzhiyun }
352*4882a593Smuzhiyun
353*4882a593Smuzhiyun /* Next iteration */
354*4882a593Smuzhiyun if (regmap_bulk_read(wg->regmap, IRQ_STATUS_BASE, p, 2)) {
355*4882a593Smuzhiyun dev_err(wg->dev, "Failed to read irq status\n");
356*4882a593Smuzhiyun break;
357*4882a593Smuzhiyun }
358*4882a593Smuzhiyun
359*4882a593Smuzhiyun pending = (p[0] & GPIO_IRQ0_MASK) | ((p[1] & GPIO_IRQ1_MASK) << 7);
360*4882a593Smuzhiyun }
361*4882a593Smuzhiyun
362*4882a593Smuzhiyun return IRQ_HANDLED;
363*4882a593Smuzhiyun }
364*4882a593Smuzhiyun
wcove_gpio_dbg_show(struct seq_file * s,struct gpio_chip * chip)365*4882a593Smuzhiyun static void wcove_gpio_dbg_show(struct seq_file *s,
366*4882a593Smuzhiyun struct gpio_chip *chip)
367*4882a593Smuzhiyun {
368*4882a593Smuzhiyun unsigned int ctlo, ctli, irq_mask, irq_status;
369*4882a593Smuzhiyun struct wcove_gpio *wg = gpiochip_get_data(chip);
370*4882a593Smuzhiyun int gpio, offset, group, ret = 0;
371*4882a593Smuzhiyun
372*4882a593Smuzhiyun for (gpio = 0; gpio < WCOVE_GPIO_NUM; gpio++) {
373*4882a593Smuzhiyun group = gpio < GROUP0_NR_IRQS ? 0 : 1;
374*4882a593Smuzhiyun ret += regmap_read(wg->regmap, to_reg(gpio, CTRL_OUT), &ctlo);
375*4882a593Smuzhiyun ret += regmap_read(wg->regmap, to_reg(gpio, CTRL_IN), &ctli);
376*4882a593Smuzhiyun ret += regmap_read(wg->regmap, IRQ_MASK_BASE + group,
377*4882a593Smuzhiyun &irq_mask);
378*4882a593Smuzhiyun ret += regmap_read(wg->regmap, IRQ_STATUS_BASE + group,
379*4882a593Smuzhiyun &irq_status);
380*4882a593Smuzhiyun if (ret) {
381*4882a593Smuzhiyun pr_err("Failed to read registers: ctrl out/in or irq status/mask\n");
382*4882a593Smuzhiyun break;
383*4882a593Smuzhiyun }
384*4882a593Smuzhiyun
385*4882a593Smuzhiyun offset = gpio % 8;
386*4882a593Smuzhiyun seq_printf(s, " gpio-%-2d %s %s %s %s ctlo=%2x,%s %s\n",
387*4882a593Smuzhiyun gpio, ctlo & CTLO_DIR_OUT ? "out" : "in ",
388*4882a593Smuzhiyun ctli & 0x1 ? "hi" : "lo",
389*4882a593Smuzhiyun ctli & CTLI_INTCNT_NE ? "fall" : " ",
390*4882a593Smuzhiyun ctli & CTLI_INTCNT_PE ? "rise" : " ",
391*4882a593Smuzhiyun ctlo,
392*4882a593Smuzhiyun irq_mask & BIT(offset) ? "mask " : "unmask",
393*4882a593Smuzhiyun irq_status & BIT(offset) ? "pending" : " ");
394*4882a593Smuzhiyun }
395*4882a593Smuzhiyun }
396*4882a593Smuzhiyun
wcove_gpio_probe(struct platform_device * pdev)397*4882a593Smuzhiyun static int wcove_gpio_probe(struct platform_device *pdev)
398*4882a593Smuzhiyun {
399*4882a593Smuzhiyun struct intel_soc_pmic *pmic;
400*4882a593Smuzhiyun struct wcove_gpio *wg;
401*4882a593Smuzhiyun int virq, ret, irq;
402*4882a593Smuzhiyun struct device *dev;
403*4882a593Smuzhiyun struct gpio_irq_chip *girq;
404*4882a593Smuzhiyun
405*4882a593Smuzhiyun /*
406*4882a593Smuzhiyun * This gpio platform device is created by a mfd device (see
407*4882a593Smuzhiyun * drivers/mfd/intel_soc_pmic_bxtwc.c for details). Information
408*4882a593Smuzhiyun * shared by all sub-devices created by the mfd device, the regmap
409*4882a593Smuzhiyun * pointer for instance, is stored as driver data of the mfd device
410*4882a593Smuzhiyun * driver.
411*4882a593Smuzhiyun */
412*4882a593Smuzhiyun pmic = dev_get_drvdata(pdev->dev.parent);
413*4882a593Smuzhiyun if (!pmic)
414*4882a593Smuzhiyun return -ENODEV;
415*4882a593Smuzhiyun
416*4882a593Smuzhiyun irq = platform_get_irq(pdev, 0);
417*4882a593Smuzhiyun if (irq < 0)
418*4882a593Smuzhiyun return irq;
419*4882a593Smuzhiyun
420*4882a593Smuzhiyun dev = &pdev->dev;
421*4882a593Smuzhiyun
422*4882a593Smuzhiyun wg = devm_kzalloc(dev, sizeof(*wg), GFP_KERNEL);
423*4882a593Smuzhiyun if (!wg)
424*4882a593Smuzhiyun return -ENOMEM;
425*4882a593Smuzhiyun
426*4882a593Smuzhiyun wg->regmap_irq_chip = pmic->irq_chip_data;
427*4882a593Smuzhiyun
428*4882a593Smuzhiyun platform_set_drvdata(pdev, wg);
429*4882a593Smuzhiyun
430*4882a593Smuzhiyun mutex_init(&wg->buslock);
431*4882a593Smuzhiyun wg->chip.label = KBUILD_MODNAME;
432*4882a593Smuzhiyun wg->chip.direction_input = wcove_gpio_dir_in;
433*4882a593Smuzhiyun wg->chip.direction_output = wcove_gpio_dir_out;
434*4882a593Smuzhiyun wg->chip.get_direction = wcove_gpio_get_direction;
435*4882a593Smuzhiyun wg->chip.get = wcove_gpio_get;
436*4882a593Smuzhiyun wg->chip.set = wcove_gpio_set;
437*4882a593Smuzhiyun wg->chip.set_config = wcove_gpio_set_config,
438*4882a593Smuzhiyun wg->chip.base = -1;
439*4882a593Smuzhiyun wg->chip.ngpio = WCOVE_VGPIO_NUM;
440*4882a593Smuzhiyun wg->chip.can_sleep = true;
441*4882a593Smuzhiyun wg->chip.parent = pdev->dev.parent;
442*4882a593Smuzhiyun wg->chip.dbg_show = wcove_gpio_dbg_show;
443*4882a593Smuzhiyun wg->dev = dev;
444*4882a593Smuzhiyun wg->regmap = pmic->regmap;
445*4882a593Smuzhiyun
446*4882a593Smuzhiyun virq = regmap_irq_get_virq(wg->regmap_irq_chip, irq);
447*4882a593Smuzhiyun if (virq < 0) {
448*4882a593Smuzhiyun dev_err(dev, "Failed to get virq by irq %d\n", irq);
449*4882a593Smuzhiyun return virq;
450*4882a593Smuzhiyun }
451*4882a593Smuzhiyun
452*4882a593Smuzhiyun girq = &wg->chip.irq;
453*4882a593Smuzhiyun girq->chip = &wcove_irqchip;
454*4882a593Smuzhiyun /* This will let us handle the parent IRQ in the driver */
455*4882a593Smuzhiyun girq->parent_handler = NULL;
456*4882a593Smuzhiyun girq->num_parents = 0;
457*4882a593Smuzhiyun girq->parents = NULL;
458*4882a593Smuzhiyun girq->default_type = IRQ_TYPE_NONE;
459*4882a593Smuzhiyun girq->handler = handle_simple_irq;
460*4882a593Smuzhiyun girq->threaded = true;
461*4882a593Smuzhiyun
462*4882a593Smuzhiyun ret = devm_request_threaded_irq(dev, virq, NULL, wcove_gpio_irq_handler,
463*4882a593Smuzhiyun IRQF_ONESHOT, pdev->name, wg);
464*4882a593Smuzhiyun if (ret) {
465*4882a593Smuzhiyun dev_err(dev, "Failed to request irq %d\n", virq);
466*4882a593Smuzhiyun return ret;
467*4882a593Smuzhiyun }
468*4882a593Smuzhiyun
469*4882a593Smuzhiyun ret = devm_gpiochip_add_data(dev, &wg->chip, wg);
470*4882a593Smuzhiyun if (ret) {
471*4882a593Smuzhiyun dev_err(dev, "Failed to add gpiochip: %d\n", ret);
472*4882a593Smuzhiyun return ret;
473*4882a593Smuzhiyun }
474*4882a593Smuzhiyun
475*4882a593Smuzhiyun /* Enable GPIO0 interrupts */
476*4882a593Smuzhiyun ret = regmap_update_bits(wg->regmap, IRQ_MASK_BASE, GPIO_IRQ0_MASK,
477*4882a593Smuzhiyun 0x00);
478*4882a593Smuzhiyun if (ret)
479*4882a593Smuzhiyun return ret;
480*4882a593Smuzhiyun
481*4882a593Smuzhiyun /* Enable GPIO1 interrupts */
482*4882a593Smuzhiyun ret = regmap_update_bits(wg->regmap, IRQ_MASK_BASE + 1, GPIO_IRQ1_MASK,
483*4882a593Smuzhiyun 0x00);
484*4882a593Smuzhiyun if (ret)
485*4882a593Smuzhiyun return ret;
486*4882a593Smuzhiyun
487*4882a593Smuzhiyun return 0;
488*4882a593Smuzhiyun }
489*4882a593Smuzhiyun
490*4882a593Smuzhiyun /*
491*4882a593Smuzhiyun * Whiskey Cove PMIC itself is a analog device(but with digital control
492*4882a593Smuzhiyun * interface) providing power management support for other devices in
493*4882a593Smuzhiyun * the accompanied SoC, so we have no .pm for Whiskey Cove GPIO driver.
494*4882a593Smuzhiyun */
495*4882a593Smuzhiyun static struct platform_driver wcove_gpio_driver = {
496*4882a593Smuzhiyun .driver = {
497*4882a593Smuzhiyun .name = "bxt_wcove_gpio",
498*4882a593Smuzhiyun },
499*4882a593Smuzhiyun .probe = wcove_gpio_probe,
500*4882a593Smuzhiyun };
501*4882a593Smuzhiyun
502*4882a593Smuzhiyun module_platform_driver(wcove_gpio_driver);
503*4882a593Smuzhiyun
504*4882a593Smuzhiyun MODULE_AUTHOR("Ajay Thomas <ajay.thomas.david.rajamanickam@intel.com>");
505*4882a593Smuzhiyun MODULE_AUTHOR("Bin Gao <bin.gao@intel.com>");
506*4882a593Smuzhiyun MODULE_DESCRIPTION("Intel Whiskey Cove GPIO Driver");
507*4882a593Smuzhiyun MODULE_LICENSE("GPL v2");
508*4882a593Smuzhiyun MODULE_ALIAS("platform:bxt_wcove_gpio");
509