1e6cbbe42SPatrick Rudolph // SPDX-License-Identifier: GPL-2.0-only
2e6cbbe42SPatrick Rudolph /*
3e6cbbe42SPatrick Rudolph  * CY8C95X0 20/40/60 pin I2C GPIO port expander with interrupt support
4e6cbbe42SPatrick Rudolph  *
5e6cbbe42SPatrick Rudolph  * Copyright (C) 2022 9elements GmbH
663e23304SAndy Shevchenko  * Authors: Patrick Rudolph <patrick.rudolph@9elements.com>
763e23304SAndy Shevchenko  *	    Naresh Solanki <Naresh.Solanki@9elements.com>
8e6cbbe42SPatrick Rudolph  */
9e6cbbe42SPatrick Rudolph 
10785b1bd8SAndy Shevchenko #include <linux/acpi.h>
11e6cbbe42SPatrick Rudolph #include <linux/bitmap.h>
12785b1bd8SAndy Shevchenko #include <linux/dmi.h>
13e6cbbe42SPatrick Rudolph #include <linux/gpio/driver.h>
14e6cbbe42SPatrick Rudolph #include <linux/gpio/consumer.h>
15e6cbbe42SPatrick Rudolph #include <linux/i2c.h>
16e6cbbe42SPatrick Rudolph #include <linux/init.h>
17e6cbbe42SPatrick Rudolph #include <linux/interrupt.h>
188586466eSAndy Shevchenko #include <linux/mod_devicetable.h>
19e6cbbe42SPatrick Rudolph #include <linux/module.h>
208586466eSAndy Shevchenko #include <linux/property.h>
218586466eSAndy Shevchenko #include <linux/regmap.h>
228586466eSAndy Shevchenko #include <linux/regulator/consumer.h>
239c0c7525SAndy Shevchenko #include <linux/seq_file.h>
248586466eSAndy Shevchenko 
25a039dfb9SAndy Shevchenko #include <linux/pinctrl/consumer.h>
26e6cbbe42SPatrick Rudolph #include <linux/pinctrl/pinconf.h>
27e6cbbe42SPatrick Rudolph #include <linux/pinctrl/pinconf-generic.h>
28a039dfb9SAndy Shevchenko #include <linux/pinctrl/pinctrl.h>
29e6cbbe42SPatrick Rudolph #include <linux/pinctrl/pinmux.h>
30e6cbbe42SPatrick Rudolph 
31e6cbbe42SPatrick Rudolph /* Fast access registers */
32e6cbbe42SPatrick Rudolph #define CY8C95X0_INPUT		0x00
33e6cbbe42SPatrick Rudolph #define CY8C95X0_OUTPUT		0x08
34e6cbbe42SPatrick Rudolph #define CY8C95X0_INTSTATUS	0x10
35e6cbbe42SPatrick Rudolph 
36e6cbbe42SPatrick Rudolph #define CY8C95X0_INPUT_(x)	(CY8C95X0_INPUT + (x))
37e6cbbe42SPatrick Rudolph #define CY8C95X0_OUTPUT_(x)	(CY8C95X0_OUTPUT + (x))
38e6cbbe42SPatrick Rudolph #define CY8C95X0_INTSTATUS_(x)	(CY8C95X0_INTSTATUS + (x))
39e6cbbe42SPatrick Rudolph 
40e6cbbe42SPatrick Rudolph /* Port Select configures the port */
41e6cbbe42SPatrick Rudolph #define CY8C95X0_PORTSEL	0x18
4263e23304SAndy Shevchenko /* Port settings, write PORTSEL first */
43e6cbbe42SPatrick Rudolph #define CY8C95X0_INTMASK	0x19
44e6cbbe42SPatrick Rudolph #define CY8C95X0_PWMSEL		0x1A
45e6cbbe42SPatrick Rudolph #define CY8C95X0_INVERT		0x1B
46e6cbbe42SPatrick Rudolph #define CY8C95X0_DIRECTION	0x1C
47e6cbbe42SPatrick Rudolph /* Drive mode register change state on writing '1' */
48e6cbbe42SPatrick Rudolph #define CY8C95X0_DRV_PU		0x1D
49e6cbbe42SPatrick Rudolph #define CY8C95X0_DRV_PD		0x1E
50e6cbbe42SPatrick Rudolph #define CY8C95X0_DRV_ODH	0x1F
51e6cbbe42SPatrick Rudolph #define CY8C95X0_DRV_ODL	0x20
52e6cbbe42SPatrick Rudolph #define CY8C95X0_DRV_PP_FAST	0x21
53e6cbbe42SPatrick Rudolph #define CY8C95X0_DRV_PP_SLOW	0x22
54e6cbbe42SPatrick Rudolph #define CY8C95X0_DRV_HIZ	0x23
55e6cbbe42SPatrick Rudolph #define CY8C95X0_DEVID		0x2E
56e6cbbe42SPatrick Rudolph #define CY8C95X0_WATCHDOG	0x2F
57e6cbbe42SPatrick Rudolph #define CY8C95X0_COMMAND	0x30
58e6cbbe42SPatrick Rudolph 
59e6cbbe42SPatrick Rudolph #define CY8C95X0_PIN_TO_OFFSET(x) (((x) >= 20) ? ((x) + 4) : (x))
60e6cbbe42SPatrick Rudolph 
61e6cbbe42SPatrick Rudolph static const struct i2c_device_id cy8c95x0_id[] = {
62e6cbbe42SPatrick Rudolph 	{ "cy8c9520", 20, },
63e6cbbe42SPatrick Rudolph 	{ "cy8c9540", 40, },
64e6cbbe42SPatrick Rudolph 	{ "cy8c9560", 60, },
65e6cbbe42SPatrick Rudolph 	{ }
66e6cbbe42SPatrick Rudolph };
67e6cbbe42SPatrick Rudolph MODULE_DEVICE_TABLE(i2c, cy8c95x0_id);
68e6cbbe42SPatrick Rudolph 
69e6cbbe42SPatrick Rudolph #define OF_CY8C95X(__nrgpio) ((void *)(__nrgpio))
70e6cbbe42SPatrick Rudolph 
71e6cbbe42SPatrick Rudolph static const struct of_device_id cy8c95x0_dt_ids[] = {
72e6cbbe42SPatrick Rudolph 	{ .compatible = "cypress,cy8c9520", .data = OF_CY8C95X(20), },
73e6cbbe42SPatrick Rudolph 	{ .compatible = "cypress,cy8c9540", .data = OF_CY8C95X(40), },
74e6cbbe42SPatrick Rudolph 	{ .compatible = "cypress,cy8c9560", .data = OF_CY8C95X(60), },
75e6cbbe42SPatrick Rudolph 	{ }
76e6cbbe42SPatrick Rudolph };
77e6cbbe42SPatrick Rudolph MODULE_DEVICE_TABLE(of, cy8c95x0_dt_ids);
78e6cbbe42SPatrick Rudolph 
79785b1bd8SAndy Shevchenko static const struct acpi_gpio_params cy8c95x0_irq_gpios = { 0, 0, true };
80785b1bd8SAndy Shevchenko 
81785b1bd8SAndy Shevchenko static const struct acpi_gpio_mapping cy8c95x0_acpi_irq_gpios[] = {
82785b1bd8SAndy Shevchenko 	{ "irq-gpios", &cy8c95x0_irq_gpios, 1, ACPI_GPIO_QUIRK_ABSOLUTE_NUMBER },
83785b1bd8SAndy Shevchenko 	{ }
84785b1bd8SAndy Shevchenko };
85785b1bd8SAndy Shevchenko 
cy8c95x0_acpi_get_irq(struct device * dev)86785b1bd8SAndy Shevchenko static int cy8c95x0_acpi_get_irq(struct device *dev)
87785b1bd8SAndy Shevchenko {
88785b1bd8SAndy Shevchenko 	int ret;
89785b1bd8SAndy Shevchenko 
90785b1bd8SAndy Shevchenko 	ret = devm_acpi_dev_add_driver_gpios(dev, cy8c95x0_acpi_irq_gpios);
91785b1bd8SAndy Shevchenko 	if (ret)
92785b1bd8SAndy Shevchenko 		dev_warn(dev, "can't add GPIO ACPI mapping\n");
93785b1bd8SAndy Shevchenko 
94785b1bd8SAndy Shevchenko 	ret = acpi_dev_gpio_irq_get_by(ACPI_COMPANION(dev), "irq-gpios", 0);
95785b1bd8SAndy Shevchenko 	if (ret < 0)
96785b1bd8SAndy Shevchenko 		return ret;
97785b1bd8SAndy Shevchenko 
98785b1bd8SAndy Shevchenko 	dev_info(dev, "ACPI interrupt quirk (IRQ %d)\n", ret);
99785b1bd8SAndy Shevchenko 	return ret;
100785b1bd8SAndy Shevchenko }
101785b1bd8SAndy Shevchenko 
102785b1bd8SAndy Shevchenko static const struct dmi_system_id cy8c95x0_dmi_acpi_irq_info[] = {
103785b1bd8SAndy Shevchenko 	{
104785b1bd8SAndy Shevchenko 		/*
105785b1bd8SAndy Shevchenko 		 * On Intel Galileo Gen 1 board the IRQ pin is provided
106785b1bd8SAndy Shevchenko 		 * as an absolute number instead of being relative.
107785b1bd8SAndy Shevchenko 		 * Since first controller (gpio-sch.c) and second
108785b1bd8SAndy Shevchenko 		 * (gpio-dwapb.c) are at the fixed bases, we may safely
109785b1bd8SAndy Shevchenko 		 * refer to the number in the global space to get an IRQ
110785b1bd8SAndy Shevchenko 		 * out of it.
111785b1bd8SAndy Shevchenko 		 */
112785b1bd8SAndy Shevchenko 		.matches = {
113785b1bd8SAndy Shevchenko 			DMI_EXACT_MATCH(DMI_BOARD_NAME, "Galileo"),
114785b1bd8SAndy Shevchenko 		},
115785b1bd8SAndy Shevchenko 	},
116785b1bd8SAndy Shevchenko 	{}
117785b1bd8SAndy Shevchenko };
118785b1bd8SAndy Shevchenko 
119e6cbbe42SPatrick Rudolph #define MAX_BANK 8
120e6cbbe42SPatrick Rudolph #define BANK_SZ 8
121e6cbbe42SPatrick Rudolph #define MAX_LINE	(MAX_BANK * BANK_SZ)
122e6cbbe42SPatrick Rudolph 
123e6cbbe42SPatrick Rudolph #define CY8C95X0_GPIO_MASK		GENMASK(7, 0)
124e6cbbe42SPatrick Rudolph 
125e6cbbe42SPatrick Rudolph /**
126e6cbbe42SPatrick Rudolph  * struct cy8c95x0_pinctrl - driver data
127e6cbbe42SPatrick Rudolph  * @regmap:         Device's regmap
128e6cbbe42SPatrick Rudolph  * @irq_lock:       IRQ bus lock
129e6cbbe42SPatrick Rudolph  * @i2c_lock:       Mutex for the device internal mux register
130e6cbbe42SPatrick Rudolph  * @irq_mask:       I/O bits affected by interrupts
131e6cbbe42SPatrick Rudolph  * @irq_trig_raise: I/O bits affected by raising voltage level
132e6cbbe42SPatrick Rudolph  * @irq_trig_fall:  I/O bits affected by falling voltage level
133e6cbbe42SPatrick Rudolph  * @irq_trig_low:   I/O bits affected by a low voltage level
134e6cbbe42SPatrick Rudolph  * @irq_trig_high:  I/O bits affected by a high voltage level
135e6cbbe42SPatrick Rudolph  * @push_pull:      I/O bits configured as push pull driver
136e6cbbe42SPatrick Rudolph  * @shiftmask:      Mask used to compensate for Gport2 width
137e6cbbe42SPatrick Rudolph  * @nport:          Number of Gports in this chip
138e6cbbe42SPatrick Rudolph  * @gpio_chip:      gpiolib chip
139e6cbbe42SPatrick Rudolph  * @driver_data:    private driver data
140e6cbbe42SPatrick Rudolph  * @regulator:      Pointer to the regulator for the IC
141e6cbbe42SPatrick Rudolph  * @dev:            struct device
142e6cbbe42SPatrick Rudolph  * @pctldev:        pin controller device
143e6cbbe42SPatrick Rudolph  * @pinctrl_desc:   pin controller description
144e6cbbe42SPatrick Rudolph  * @name:           Chip controller name
145e6cbbe42SPatrick Rudolph  * @tpin:           Total number of pins
146e6cbbe42SPatrick Rudolph  */
147e6cbbe42SPatrick Rudolph struct cy8c95x0_pinctrl {
148e6cbbe42SPatrick Rudolph 	struct regmap *regmap;
149e6cbbe42SPatrick Rudolph 	struct mutex irq_lock;
150e6cbbe42SPatrick Rudolph 	struct mutex i2c_lock;
151e6cbbe42SPatrick Rudolph 	DECLARE_BITMAP(irq_mask, MAX_LINE);
152e6cbbe42SPatrick Rudolph 	DECLARE_BITMAP(irq_trig_raise, MAX_LINE);
153e6cbbe42SPatrick Rudolph 	DECLARE_BITMAP(irq_trig_fall, MAX_LINE);
154e6cbbe42SPatrick Rudolph 	DECLARE_BITMAP(irq_trig_low, MAX_LINE);
155e6cbbe42SPatrick Rudolph 	DECLARE_BITMAP(irq_trig_high, MAX_LINE);
156e6cbbe42SPatrick Rudolph 	DECLARE_BITMAP(push_pull, MAX_LINE);
157e6cbbe42SPatrick Rudolph 	DECLARE_BITMAP(shiftmask, MAX_LINE);
158e6cbbe42SPatrick Rudolph 	int nport;
159e6cbbe42SPatrick Rudolph 	struct gpio_chip gpio_chip;
160e6cbbe42SPatrick Rudolph 	unsigned long driver_data;
161e6cbbe42SPatrick Rudolph 	struct regulator *regulator;
162e6cbbe42SPatrick Rudolph 	struct device *dev;
163e6cbbe42SPatrick Rudolph 	struct pinctrl_dev *pctldev;
164e6cbbe42SPatrick Rudolph 	struct pinctrl_desc pinctrl_desc;
165e6cbbe42SPatrick Rudolph 	char name[32];
166e6cbbe42SPatrick Rudolph 	unsigned int tpin;
16799084881SPatrick Rudolph 	struct gpio_desc *gpio_reset;
168e6cbbe42SPatrick Rudolph };
169e6cbbe42SPatrick Rudolph 
170e6cbbe42SPatrick Rudolph static const struct pinctrl_pin_desc cy8c9560_pins[] = {
171e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(0, "gp00"),
172e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(1, "gp01"),
173e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(2, "gp02"),
174e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(3, "gp03"),
175e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(4, "gp04"),
176e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(5, "gp05"),
177e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(6, "gp06"),
178e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(7, "gp07"),
179e6cbbe42SPatrick Rudolph 
180e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(8, "gp10"),
181e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(9, "gp11"),
182e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(10, "gp12"),
183e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(11, "gp13"),
184e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(12, "gp14"),
185e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(13, "gp15"),
186e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(14, "gp16"),
187e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(15, "gp17"),
188e6cbbe42SPatrick Rudolph 
189e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(16, "gp20"),
190e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(17, "gp21"),
191e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(18, "gp22"),
192e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(19, "gp23"),
193e6cbbe42SPatrick Rudolph 
194e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(20, "gp30"),
195e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(21, "gp31"),
196e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(22, "gp32"),
197e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(23, "gp33"),
198e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(24, "gp34"),
199e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(25, "gp35"),
200e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(26, "gp36"),
201e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(27, "gp37"),
202e6cbbe42SPatrick Rudolph 
203e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(28, "gp40"),
204e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(29, "gp41"),
205e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(30, "gp42"),
206e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(31, "gp43"),
207e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(32, "gp44"),
208e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(33, "gp45"),
209e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(34, "gp46"),
210e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(35, "gp47"),
211e6cbbe42SPatrick Rudolph 
212e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(36, "gp50"),
213e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(37, "gp51"),
214e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(38, "gp52"),
215e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(39, "gp53"),
216e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(40, "gp54"),
217e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(41, "gp55"),
218e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(42, "gp56"),
219e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(43, "gp57"),
220e6cbbe42SPatrick Rudolph 
221e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(44, "gp60"),
222e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(45, "gp61"),
223e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(46, "gp62"),
224e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(47, "gp63"),
225e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(48, "gp64"),
226e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(49, "gp65"),
227e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(50, "gp66"),
228e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(51, "gp67"),
229e6cbbe42SPatrick Rudolph 
230e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(52, "gp70"),
231e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(53, "gp71"),
232e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(54, "gp72"),
233e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(55, "gp73"),
234e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(56, "gp74"),
235e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(57, "gp75"),
236e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(58, "gp76"),
237e6cbbe42SPatrick Rudolph 	PINCTRL_PIN(59, "gp77"),
238e6cbbe42SPatrick Rudolph };
239e6cbbe42SPatrick Rudolph 
240e6cbbe42SPatrick Rudolph static const char * const cy8c95x0_groups[] = {
241e6cbbe42SPatrick Rudolph 	"gp00",
242e6cbbe42SPatrick Rudolph 	"gp01",
243e6cbbe42SPatrick Rudolph 	"gp02",
244e6cbbe42SPatrick Rudolph 	"gp03",
245e6cbbe42SPatrick Rudolph 	"gp04",
246e6cbbe42SPatrick Rudolph 	"gp05",
247e6cbbe42SPatrick Rudolph 	"gp06",
248e6cbbe42SPatrick Rudolph 	"gp07",
249e6cbbe42SPatrick Rudolph 
250e6cbbe42SPatrick Rudolph 	"gp10",
251e6cbbe42SPatrick Rudolph 	"gp11",
252e6cbbe42SPatrick Rudolph 	"gp12",
253e6cbbe42SPatrick Rudolph 	"gp13",
254e6cbbe42SPatrick Rudolph 	"gp14",
255e6cbbe42SPatrick Rudolph 	"gp15",
256e6cbbe42SPatrick Rudolph 	"gp16",
257e6cbbe42SPatrick Rudolph 	"gp17",
258e6cbbe42SPatrick Rudolph 
259e6cbbe42SPatrick Rudolph 	"gp20",
260e6cbbe42SPatrick Rudolph 	"gp21",
261e6cbbe42SPatrick Rudolph 	"gp22",
262e6cbbe42SPatrick Rudolph 	"gp23",
263e6cbbe42SPatrick Rudolph 
264e6cbbe42SPatrick Rudolph 	"gp30",
265e6cbbe42SPatrick Rudolph 	"gp31",
266e6cbbe42SPatrick Rudolph 	"gp32",
267e6cbbe42SPatrick Rudolph 	"gp33",
268e6cbbe42SPatrick Rudolph 	"gp34",
269e6cbbe42SPatrick Rudolph 	"gp35",
270e6cbbe42SPatrick Rudolph 	"gp36",
271e6cbbe42SPatrick Rudolph 	"gp37",
272e6cbbe42SPatrick Rudolph 
273e6cbbe42SPatrick Rudolph 	"gp40",
274e6cbbe42SPatrick Rudolph 	"gp41",
275e6cbbe42SPatrick Rudolph 	"gp42",
276e6cbbe42SPatrick Rudolph 	"gp43",
277e6cbbe42SPatrick Rudolph 	"gp44",
278e6cbbe42SPatrick Rudolph 	"gp45",
279e6cbbe42SPatrick Rudolph 	"gp46",
280e6cbbe42SPatrick Rudolph 	"gp47",
281e6cbbe42SPatrick Rudolph 
282e6cbbe42SPatrick Rudolph 	"gp50",
283e6cbbe42SPatrick Rudolph 	"gp51",
284e6cbbe42SPatrick Rudolph 	"gp52",
285e6cbbe42SPatrick Rudolph 	"gp53",
286e6cbbe42SPatrick Rudolph 	"gp54",
287e6cbbe42SPatrick Rudolph 	"gp55",
288e6cbbe42SPatrick Rudolph 	"gp56",
289e6cbbe42SPatrick Rudolph 	"gp57",
290e6cbbe42SPatrick Rudolph 
291e6cbbe42SPatrick Rudolph 	"gp60",
292e6cbbe42SPatrick Rudolph 	"gp61",
293e6cbbe42SPatrick Rudolph 	"gp62",
294e6cbbe42SPatrick Rudolph 	"gp63",
295e6cbbe42SPatrick Rudolph 	"gp64",
296e6cbbe42SPatrick Rudolph 	"gp65",
297e6cbbe42SPatrick Rudolph 	"gp66",
298e6cbbe42SPatrick Rudolph 	"gp67",
299e6cbbe42SPatrick Rudolph 
300e6cbbe42SPatrick Rudolph 	"gp70",
301e6cbbe42SPatrick Rudolph 	"gp71",
302e6cbbe42SPatrick Rudolph 	"gp72",
303e6cbbe42SPatrick Rudolph 	"gp73",
304e6cbbe42SPatrick Rudolph 	"gp74",
305e6cbbe42SPatrick Rudolph 	"gp75",
306e6cbbe42SPatrick Rudolph 	"gp76",
307e6cbbe42SPatrick Rudolph 	"gp77",
308e6cbbe42SPatrick Rudolph };
309e6cbbe42SPatrick Rudolph 
3105f0a1661SPatrick Rudolph static int cy8c95x0_pinmux_direction(struct cy8c95x0_pinctrl *chip,
3115f0a1661SPatrick Rudolph 				     unsigned int pin, bool input);
3125f0a1661SPatrick Rudolph 
cypress_get_port(struct cy8c95x0_pinctrl * chip,unsigned int pin)313e6cbbe42SPatrick Rudolph static inline u8 cypress_get_port(struct cy8c95x0_pinctrl *chip, unsigned int pin)
314e6cbbe42SPatrick Rudolph {
315e6cbbe42SPatrick Rudolph 	/* Account for GPORT2 which only has 4 bits */
316e6cbbe42SPatrick Rudolph 	return CY8C95X0_PIN_TO_OFFSET(pin) / BANK_SZ;
317e6cbbe42SPatrick Rudolph }
318e6cbbe42SPatrick Rudolph 
cypress_get_pin_mask(struct cy8c95x0_pinctrl * chip,unsigned int pin)319e6cbbe42SPatrick Rudolph static int cypress_get_pin_mask(struct cy8c95x0_pinctrl *chip, unsigned int pin)
320e6cbbe42SPatrick Rudolph {
321e6cbbe42SPatrick Rudolph 	/* Account for GPORT2 which only has 4 bits */
322e6cbbe42SPatrick Rudolph 	return BIT(CY8C95X0_PIN_TO_OFFSET(pin) % BANK_SZ);
323e6cbbe42SPatrick Rudolph }
324e6cbbe42SPatrick Rudolph 
cy8c95x0_readable_register(struct device * dev,unsigned int reg)325e6cbbe42SPatrick Rudolph static bool cy8c95x0_readable_register(struct device *dev, unsigned int reg)
326e6cbbe42SPatrick Rudolph {
327e6cbbe42SPatrick Rudolph 	switch (reg) {
328e6cbbe42SPatrick Rudolph 	case 0x24 ... 0x27:
329e6cbbe42SPatrick Rudolph 		return false;
330c3e40952SAndy Shevchenko 	default:
331e6cbbe42SPatrick Rudolph 		return true;
332e6cbbe42SPatrick Rudolph 	}
333c3e40952SAndy Shevchenko }
334e6cbbe42SPatrick Rudolph 
cy8c95x0_writeable_register(struct device * dev,unsigned int reg)335e6cbbe42SPatrick Rudolph static bool cy8c95x0_writeable_register(struct device *dev, unsigned int reg)
336e6cbbe42SPatrick Rudolph {
337e6cbbe42SPatrick Rudolph 	switch (reg) {
338e6cbbe42SPatrick Rudolph 	case CY8C95X0_INPUT_(0) ... CY8C95X0_INPUT_(7):
339e6cbbe42SPatrick Rudolph 		return false;
340e6cbbe42SPatrick Rudolph 	case CY8C95X0_DEVID:
341e6cbbe42SPatrick Rudolph 		return false;
342e6cbbe42SPatrick Rudolph 	case 0x24 ... 0x27:
343e6cbbe42SPatrick Rudolph 		return false;
344c3e40952SAndy Shevchenko 	default:
345e6cbbe42SPatrick Rudolph 		return true;
346e6cbbe42SPatrick Rudolph 	}
347c3e40952SAndy Shevchenko }
348e6cbbe42SPatrick Rudolph 
cy8c95x0_volatile_register(struct device * dev,unsigned int reg)349e6cbbe42SPatrick Rudolph static bool cy8c95x0_volatile_register(struct device *dev, unsigned int reg)
350e6cbbe42SPatrick Rudolph {
351e6cbbe42SPatrick Rudolph 	switch (reg) {
352e6cbbe42SPatrick Rudolph 	case CY8C95X0_INPUT_(0) ... CY8C95X0_INPUT_(7):
353e6cbbe42SPatrick Rudolph 	case CY8C95X0_INTSTATUS_(0) ... CY8C95X0_INTSTATUS_(7):
354e6cbbe42SPatrick Rudolph 	case CY8C95X0_INTMASK:
355e6cbbe42SPatrick Rudolph 	case CY8C95X0_INVERT:
356e6cbbe42SPatrick Rudolph 	case CY8C95X0_PWMSEL:
357e6cbbe42SPatrick Rudolph 	case CY8C95X0_DIRECTION:
358e6cbbe42SPatrick Rudolph 	case CY8C95X0_DRV_PU:
359e6cbbe42SPatrick Rudolph 	case CY8C95X0_DRV_PD:
360e6cbbe42SPatrick Rudolph 	case CY8C95X0_DRV_ODH:
361e6cbbe42SPatrick Rudolph 	case CY8C95X0_DRV_ODL:
362e6cbbe42SPatrick Rudolph 	case CY8C95X0_DRV_PP_FAST:
363e6cbbe42SPatrick Rudolph 	case CY8C95X0_DRV_PP_SLOW:
364e6cbbe42SPatrick Rudolph 	case CY8C95X0_DRV_HIZ:
365e6cbbe42SPatrick Rudolph 		return true;
366e662d349SAndy Shevchenko 	default:
367e6cbbe42SPatrick Rudolph 		return false;
368e6cbbe42SPatrick Rudolph 	}
369e662d349SAndy Shevchenko }
370e6cbbe42SPatrick Rudolph 
cy8c95x0_precious_register(struct device * dev,unsigned int reg)371e6cbbe42SPatrick Rudolph static bool cy8c95x0_precious_register(struct device *dev, unsigned int reg)
372e6cbbe42SPatrick Rudolph {
373e6cbbe42SPatrick Rudolph 	switch (reg) {
374e6cbbe42SPatrick Rudolph 	case CY8C95X0_INTSTATUS_(0) ... CY8C95X0_INTSTATUS_(7):
375e6cbbe42SPatrick Rudolph 		return true;
376c3e40952SAndy Shevchenko 	default:
377e6cbbe42SPatrick Rudolph 		return false;
378e6cbbe42SPatrick Rudolph 	}
379c3e40952SAndy Shevchenko }
380e6cbbe42SPatrick Rudolph 
381e6cbbe42SPatrick Rudolph static const struct reg_default cy8c95x0_reg_defaults[] = {
3829540a836SAndy Shevchenko 	{ CY8C95X0_OUTPUT_(0), GENMASK(7, 0) },
3839540a836SAndy Shevchenko 	{ CY8C95X0_OUTPUT_(1), GENMASK(7, 0) },
3849540a836SAndy Shevchenko 	{ CY8C95X0_OUTPUT_(2), GENMASK(7, 0) },
3859540a836SAndy Shevchenko 	{ CY8C95X0_OUTPUT_(3), GENMASK(7, 0) },
3869540a836SAndy Shevchenko 	{ CY8C95X0_OUTPUT_(4), GENMASK(7, 0) },
3879540a836SAndy Shevchenko 	{ CY8C95X0_OUTPUT_(5), GENMASK(7, 0) },
3889540a836SAndy Shevchenko 	{ CY8C95X0_OUTPUT_(6), GENMASK(7, 0) },
3899540a836SAndy Shevchenko 	{ CY8C95X0_OUTPUT_(7), GENMASK(7, 0) },
390e6cbbe42SPatrick Rudolph 	{ CY8C95X0_PORTSEL, 0 },
391e6cbbe42SPatrick Rudolph 	{ CY8C95X0_PWMSEL, 0 },
392e6cbbe42SPatrick Rudolph };
393e6cbbe42SPatrick Rudolph 
394e6cbbe42SPatrick Rudolph static const struct regmap_config cy8c95x0_i2c_regmap = {
395e6cbbe42SPatrick Rudolph 	.reg_bits = 8,
396e6cbbe42SPatrick Rudolph 	.val_bits = 8,
397e6cbbe42SPatrick Rudolph 
398e6cbbe42SPatrick Rudolph 	.reg_defaults = cy8c95x0_reg_defaults,
399e6cbbe42SPatrick Rudolph 	.num_reg_defaults = ARRAY_SIZE(cy8c95x0_reg_defaults),
400e6cbbe42SPatrick Rudolph 
401e6cbbe42SPatrick Rudolph 	.readable_reg = cy8c95x0_readable_register,
402e6cbbe42SPatrick Rudolph 	.writeable_reg = cy8c95x0_writeable_register,
403e6cbbe42SPatrick Rudolph 	.volatile_reg = cy8c95x0_volatile_register,
404e6cbbe42SPatrick Rudolph 	.precious_reg = cy8c95x0_precious_register,
405e6cbbe42SPatrick Rudolph 
406e6cbbe42SPatrick Rudolph 	.cache_type = REGCACHE_FLAT,
407e6cbbe42SPatrick Rudolph 	.max_register = CY8C95X0_COMMAND,
408e6cbbe42SPatrick Rudolph };
409e6cbbe42SPatrick Rudolph 
cy8c95x0_write_regs_mask(struct cy8c95x0_pinctrl * chip,int reg,unsigned long * val,unsigned long * mask)410e6cbbe42SPatrick Rudolph static int cy8c95x0_write_regs_mask(struct cy8c95x0_pinctrl *chip, int reg,
411e6cbbe42SPatrick Rudolph 				    unsigned long *val, unsigned long *mask)
412e6cbbe42SPatrick Rudolph {
413e6cbbe42SPatrick Rudolph 	DECLARE_BITMAP(tmask, MAX_LINE);
414e6cbbe42SPatrick Rudolph 	DECLARE_BITMAP(tval, MAX_LINE);
415e6cbbe42SPatrick Rudolph 	int write_val;
416e6cbbe42SPatrick Rudolph 	int ret = 0;
417e6cbbe42SPatrick Rudolph 	int i, off = 0;
418e6cbbe42SPatrick Rudolph 	u8 bits;
419e6cbbe42SPatrick Rudolph 
420e6cbbe42SPatrick Rudolph 	/* Add the 4 bit gap of Gport2 */
421e6cbbe42SPatrick Rudolph 	bitmap_andnot(tmask, mask, chip->shiftmask, MAX_LINE);
422e6cbbe42SPatrick Rudolph 	bitmap_shift_left(tmask, tmask, 4, MAX_LINE);
423e6cbbe42SPatrick Rudolph 	bitmap_replace(tmask, tmask, mask, chip->shiftmask, BANK_SZ * 3);
424e6cbbe42SPatrick Rudolph 
425e6cbbe42SPatrick Rudolph 	bitmap_andnot(tval, val, chip->shiftmask, MAX_LINE);
426e6cbbe42SPatrick Rudolph 	bitmap_shift_left(tval, tval, 4, MAX_LINE);
427e6cbbe42SPatrick Rudolph 	bitmap_replace(tval, tval, val, chip->shiftmask, BANK_SZ * 3);
428e6cbbe42SPatrick Rudolph 
429e6cbbe42SPatrick Rudolph 	mutex_lock(&chip->i2c_lock);
430e6cbbe42SPatrick Rudolph 	for (i = 0; i < chip->nport; i++) {
431e6cbbe42SPatrick Rudolph 		/* Skip over unused banks */
432e6cbbe42SPatrick Rudolph 		bits = bitmap_get_value8(tmask, i * BANK_SZ);
433e6cbbe42SPatrick Rudolph 		if (!bits)
434e6cbbe42SPatrick Rudolph 			continue;
435e6cbbe42SPatrick Rudolph 
436e6cbbe42SPatrick Rudolph 		switch (reg) {
43763e23304SAndy Shevchenko 		/* Muxed registers */
438e6cbbe42SPatrick Rudolph 		case CY8C95X0_INTMASK:
439e6cbbe42SPatrick Rudolph 		case CY8C95X0_PWMSEL:
440e6cbbe42SPatrick Rudolph 		case CY8C95X0_INVERT:
441e6cbbe42SPatrick Rudolph 		case CY8C95X0_DIRECTION:
442e6cbbe42SPatrick Rudolph 		case CY8C95X0_DRV_PU:
443e6cbbe42SPatrick Rudolph 		case CY8C95X0_DRV_PD:
444e6cbbe42SPatrick Rudolph 		case CY8C95X0_DRV_ODH:
445e6cbbe42SPatrick Rudolph 		case CY8C95X0_DRV_ODL:
446e6cbbe42SPatrick Rudolph 		case CY8C95X0_DRV_PP_FAST:
447e6cbbe42SPatrick Rudolph 		case CY8C95X0_DRV_PP_SLOW:
448e6cbbe42SPatrick Rudolph 		case CY8C95X0_DRV_HIZ:
449e6cbbe42SPatrick Rudolph 			ret = regmap_write(chip->regmap, CY8C95X0_PORTSEL, i);
450e6cbbe42SPatrick Rudolph 			if (ret < 0)
451e6cbbe42SPatrick Rudolph 				goto out;
452e6cbbe42SPatrick Rudolph 			off = reg;
453e6cbbe42SPatrick Rudolph 			break;
45463e23304SAndy Shevchenko 		/* Direct access registers */
455e6cbbe42SPatrick Rudolph 		case CY8C95X0_INPUT:
456e6cbbe42SPatrick Rudolph 		case CY8C95X0_OUTPUT:
457e6cbbe42SPatrick Rudolph 		case CY8C95X0_INTSTATUS:
458e6cbbe42SPatrick Rudolph 			off = reg + i;
459e6cbbe42SPatrick Rudolph 			break;
460e6cbbe42SPatrick Rudolph 		default:
461e6cbbe42SPatrick Rudolph 			ret = -EINVAL;
462e6cbbe42SPatrick Rudolph 			goto out;
463e6cbbe42SPatrick Rudolph 		}
464e6cbbe42SPatrick Rudolph 
465e6cbbe42SPatrick Rudolph 		write_val = bitmap_get_value8(tval, i * BANK_SZ);
466e6cbbe42SPatrick Rudolph 
467e6cbbe42SPatrick Rudolph 		ret = regmap_update_bits(chip->regmap, off, bits, write_val);
468e6cbbe42SPatrick Rudolph 		if (ret < 0)
469e6cbbe42SPatrick Rudolph 			goto out;
470e6cbbe42SPatrick Rudolph 	}
471e6cbbe42SPatrick Rudolph out:
472e6cbbe42SPatrick Rudolph 	mutex_unlock(&chip->i2c_lock);
473e6cbbe42SPatrick Rudolph 
474e6cbbe42SPatrick Rudolph 	if (ret < 0)
475e6cbbe42SPatrick Rudolph 		dev_err(chip->dev, "failed writing register %d: err %d\n", off, ret);
476e6cbbe42SPatrick Rudolph 
477e6cbbe42SPatrick Rudolph 	return ret;
478e6cbbe42SPatrick Rudolph }
479e6cbbe42SPatrick Rudolph 
cy8c95x0_read_regs_mask(struct cy8c95x0_pinctrl * chip,int reg,unsigned long * val,unsigned long * mask)480e6cbbe42SPatrick Rudolph static int cy8c95x0_read_regs_mask(struct cy8c95x0_pinctrl *chip, int reg,
481e6cbbe42SPatrick Rudolph 				   unsigned long *val, unsigned long *mask)
482e6cbbe42SPatrick Rudolph {
483e6cbbe42SPatrick Rudolph 	DECLARE_BITMAP(tmask, MAX_LINE);
484e6cbbe42SPatrick Rudolph 	DECLARE_BITMAP(tval, MAX_LINE);
485e6cbbe42SPatrick Rudolph 	DECLARE_BITMAP(tmp, MAX_LINE);
486e6cbbe42SPatrick Rudolph 	int read_val;
487e6cbbe42SPatrick Rudolph 	int ret = 0;
488e6cbbe42SPatrick Rudolph 	int i, off = 0;
489e6cbbe42SPatrick Rudolph 	u8 bits;
490e6cbbe42SPatrick Rudolph 
491e6cbbe42SPatrick Rudolph 	/* Add the 4 bit gap of Gport2 */
492e6cbbe42SPatrick Rudolph 	bitmap_andnot(tmask, mask, chip->shiftmask, MAX_LINE);
493e6cbbe42SPatrick Rudolph 	bitmap_shift_left(tmask, tmask, 4, MAX_LINE);
494e6cbbe42SPatrick Rudolph 	bitmap_replace(tmask, tmask, mask, chip->shiftmask, BANK_SZ * 3);
495e6cbbe42SPatrick Rudolph 
496e6cbbe42SPatrick Rudolph 	bitmap_andnot(tval, val, chip->shiftmask, MAX_LINE);
497e6cbbe42SPatrick Rudolph 	bitmap_shift_left(tval, tval, 4, MAX_LINE);
498e6cbbe42SPatrick Rudolph 	bitmap_replace(tval, tval, val, chip->shiftmask, BANK_SZ * 3);
499e6cbbe42SPatrick Rudolph 
500e6cbbe42SPatrick Rudolph 	mutex_lock(&chip->i2c_lock);
501e6cbbe42SPatrick Rudolph 	for (i = 0; i < chip->nport; i++) {
502e6cbbe42SPatrick Rudolph 		/* Skip over unused banks */
503e6cbbe42SPatrick Rudolph 		bits = bitmap_get_value8(tmask, i * BANK_SZ);
504e6cbbe42SPatrick Rudolph 		if (!bits)
505e6cbbe42SPatrick Rudolph 			continue;
506e6cbbe42SPatrick Rudolph 
507e6cbbe42SPatrick Rudolph 		switch (reg) {
50863e23304SAndy Shevchenko 		/* Muxed registers */
509e6cbbe42SPatrick Rudolph 		case CY8C95X0_INTMASK:
510e6cbbe42SPatrick Rudolph 		case CY8C95X0_PWMSEL:
511e6cbbe42SPatrick Rudolph 		case CY8C95X0_INVERT:
512e6cbbe42SPatrick Rudolph 		case CY8C95X0_DIRECTION:
513e6cbbe42SPatrick Rudolph 		case CY8C95X0_DRV_PU:
514e6cbbe42SPatrick Rudolph 		case CY8C95X0_DRV_PD:
515e6cbbe42SPatrick Rudolph 		case CY8C95X0_DRV_ODH:
516e6cbbe42SPatrick Rudolph 		case CY8C95X0_DRV_ODL:
517e6cbbe42SPatrick Rudolph 		case CY8C95X0_DRV_PP_FAST:
518e6cbbe42SPatrick Rudolph 		case CY8C95X0_DRV_PP_SLOW:
519e6cbbe42SPatrick Rudolph 		case CY8C95X0_DRV_HIZ:
520e6cbbe42SPatrick Rudolph 			ret = regmap_write(chip->regmap, CY8C95X0_PORTSEL, i);
521e6cbbe42SPatrick Rudolph 			if (ret < 0)
522e6cbbe42SPatrick Rudolph 				goto out;
523e6cbbe42SPatrick Rudolph 			off = reg;
524e6cbbe42SPatrick Rudolph 			break;
52563e23304SAndy Shevchenko 		/* Direct access registers */
526e6cbbe42SPatrick Rudolph 		case CY8C95X0_INPUT:
527e6cbbe42SPatrick Rudolph 		case CY8C95X0_OUTPUT:
528e6cbbe42SPatrick Rudolph 		case CY8C95X0_INTSTATUS:
529e6cbbe42SPatrick Rudolph 			off = reg + i;
530e6cbbe42SPatrick Rudolph 			break;
531e6cbbe42SPatrick Rudolph 		default:
532e6cbbe42SPatrick Rudolph 			ret = -EINVAL;
533e6cbbe42SPatrick Rudolph 			goto out;
534e6cbbe42SPatrick Rudolph 		}
535e6cbbe42SPatrick Rudolph 
536e6cbbe42SPatrick Rudolph 		ret = regmap_read(chip->regmap, off, &read_val);
537e6cbbe42SPatrick Rudolph 		if (ret < 0)
538e6cbbe42SPatrick Rudolph 			goto out;
539e6cbbe42SPatrick Rudolph 
540e6cbbe42SPatrick Rudolph 		read_val &= bits;
541e6cbbe42SPatrick Rudolph 		read_val |= bitmap_get_value8(tval, i * BANK_SZ) & ~bits;
542e6cbbe42SPatrick Rudolph 		bitmap_set_value8(tval, read_val, i * BANK_SZ);
543e6cbbe42SPatrick Rudolph 	}
544e6cbbe42SPatrick Rudolph 
545e6cbbe42SPatrick Rudolph 	/* Fill the 4 bit gap of Gport2 */
546e6cbbe42SPatrick Rudolph 	bitmap_shift_right(tmp, tval, 4, MAX_LINE);
547e6cbbe42SPatrick Rudolph 	bitmap_replace(val, tmp, tval, chip->shiftmask, MAX_LINE);
548e6cbbe42SPatrick Rudolph 
549e6cbbe42SPatrick Rudolph out:
550e6cbbe42SPatrick Rudolph 	mutex_unlock(&chip->i2c_lock);
551e6cbbe42SPatrick Rudolph 
552e6cbbe42SPatrick Rudolph 	if (ret < 0)
553e6cbbe42SPatrick Rudolph 		dev_err(chip->dev, "failed reading register %d: err %d\n", off, ret);
554e6cbbe42SPatrick Rudolph 
555e6cbbe42SPatrick Rudolph 	return ret;
556e6cbbe42SPatrick Rudolph }
557e6cbbe42SPatrick Rudolph 
cy8c95x0_gpio_direction_input(struct gpio_chip * gc,unsigned int off)558e6cbbe42SPatrick Rudolph static int cy8c95x0_gpio_direction_input(struct gpio_chip *gc, unsigned int off)
559e6cbbe42SPatrick Rudolph {
560a039dfb9SAndy Shevchenko 	return pinctrl_gpio_direction_input(gc->base + off);
561e6cbbe42SPatrick Rudolph }
562e6cbbe42SPatrick Rudolph 
cy8c95x0_gpio_direction_output(struct gpio_chip * gc,unsigned int off,int val)563e6cbbe42SPatrick Rudolph static int cy8c95x0_gpio_direction_output(struct gpio_chip *gc,
564e6cbbe42SPatrick Rudolph 					  unsigned int off, int val)
565e6cbbe42SPatrick Rudolph {
566e6cbbe42SPatrick Rudolph 	struct cy8c95x0_pinctrl *chip = gpiochip_get_data(gc);
567e6cbbe42SPatrick Rudolph 	u8 port = cypress_get_port(chip, off);
568e6cbbe42SPatrick Rudolph 	u8 outreg = CY8C95X0_OUTPUT_(port);
569e6cbbe42SPatrick Rudolph 	u8 bit = cypress_get_pin_mask(chip, off);
570e6cbbe42SPatrick Rudolph 	int ret;
571e6cbbe42SPatrick Rudolph 
57263e23304SAndy Shevchenko 	/* Set output level */
573e6cbbe42SPatrick Rudolph 	ret = regmap_write_bits(chip->regmap, outreg, bit, val ? bit : 0);
574e6cbbe42SPatrick Rudolph 	if (ret)
575e6cbbe42SPatrick Rudolph 		return ret;
576e6cbbe42SPatrick Rudolph 
577a039dfb9SAndy Shevchenko 	return pinctrl_gpio_direction_output(gc->base + off);
578e6cbbe42SPatrick Rudolph }
579e6cbbe42SPatrick Rudolph 
cy8c95x0_gpio_get_value(struct gpio_chip * gc,unsigned int off)580e6cbbe42SPatrick Rudolph static int cy8c95x0_gpio_get_value(struct gpio_chip *gc, unsigned int off)
581e6cbbe42SPatrick Rudolph {
582e6cbbe42SPatrick Rudolph 	struct cy8c95x0_pinctrl *chip = gpiochip_get_data(gc);
583e6cbbe42SPatrick Rudolph 	u8 inreg = CY8C95X0_INPUT_(cypress_get_port(chip, off));
584e6cbbe42SPatrick Rudolph 	u8 bit = cypress_get_pin_mask(chip, off);
585e6cbbe42SPatrick Rudolph 	u32 reg_val;
586e6cbbe42SPatrick Rudolph 	int ret;
587e6cbbe42SPatrick Rudolph 
588e6cbbe42SPatrick Rudolph 	ret = regmap_read(chip->regmap, inreg, &reg_val);
589e6cbbe42SPatrick Rudolph 	if (ret < 0) {
590e6cbbe42SPatrick Rudolph 		/*
591e6cbbe42SPatrick Rudolph 		 * NOTE:
59263e23304SAndy Shevchenko 		 * Diagnostic already emitted; that's all we should
593e6cbbe42SPatrick Rudolph 		 * do unless gpio_*_value_cansleep() calls become different
594e6cbbe42SPatrick Rudolph 		 * from their nonsleeping siblings (and report faults).
595e6cbbe42SPatrick Rudolph 		 */
596e6cbbe42SPatrick Rudolph 		return 0;
597e6cbbe42SPatrick Rudolph 	}
598e6cbbe42SPatrick Rudolph 
599e6cbbe42SPatrick Rudolph 	return !!(reg_val & bit);
600e6cbbe42SPatrick Rudolph }
601e6cbbe42SPatrick Rudolph 
cy8c95x0_gpio_set_value(struct gpio_chip * gc,unsigned int off,int val)602e6cbbe42SPatrick Rudolph static void cy8c95x0_gpio_set_value(struct gpio_chip *gc, unsigned int off,
603e6cbbe42SPatrick Rudolph 				    int val)
604e6cbbe42SPatrick Rudolph {
605e6cbbe42SPatrick Rudolph 	struct cy8c95x0_pinctrl *chip = gpiochip_get_data(gc);
606e6cbbe42SPatrick Rudolph 	u8 outreg = CY8C95X0_OUTPUT_(cypress_get_port(chip, off));
607e6cbbe42SPatrick Rudolph 	u8 bit = cypress_get_pin_mask(chip, off);
608e6cbbe42SPatrick Rudolph 
609e6cbbe42SPatrick Rudolph 	regmap_write_bits(chip->regmap, outreg, bit, val ? bit : 0);
610e6cbbe42SPatrick Rudolph }
611e6cbbe42SPatrick Rudolph 
cy8c95x0_gpio_get_direction(struct gpio_chip * gc,unsigned int off)612e6cbbe42SPatrick Rudolph static int cy8c95x0_gpio_get_direction(struct gpio_chip *gc, unsigned int off)
613e6cbbe42SPatrick Rudolph {
614e6cbbe42SPatrick Rudolph 	struct cy8c95x0_pinctrl *chip = gpiochip_get_data(gc);
615e6cbbe42SPatrick Rudolph 	u8 port = cypress_get_port(chip, off);
616e6cbbe42SPatrick Rudolph 	u8 bit = cypress_get_pin_mask(chip, off);
617e6cbbe42SPatrick Rudolph 	u32 reg_val;
618e6cbbe42SPatrick Rudolph 	int ret;
619e6cbbe42SPatrick Rudolph 
620e6cbbe42SPatrick Rudolph 	mutex_lock(&chip->i2c_lock);
621e6cbbe42SPatrick Rudolph 
622e6cbbe42SPatrick Rudolph 	ret = regmap_write(chip->regmap, CY8C95X0_PORTSEL, port);
623e6cbbe42SPatrick Rudolph 	if (ret < 0)
624e6cbbe42SPatrick Rudolph 		goto out;
625e6cbbe42SPatrick Rudolph 
626e6cbbe42SPatrick Rudolph 	ret = regmap_read(chip->regmap, CY8C95X0_DIRECTION, &reg_val);
627e6cbbe42SPatrick Rudolph 	if (ret < 0)
628e6cbbe42SPatrick Rudolph 		goto out;
629e6cbbe42SPatrick Rudolph 
630e6cbbe42SPatrick Rudolph 	mutex_unlock(&chip->i2c_lock);
631e6cbbe42SPatrick Rudolph 
632e6cbbe42SPatrick Rudolph 	if (reg_val & bit)
633e6cbbe42SPatrick Rudolph 		return GPIO_LINE_DIRECTION_IN;
634e6cbbe42SPatrick Rudolph 
635e6cbbe42SPatrick Rudolph 	return GPIO_LINE_DIRECTION_OUT;
636e6cbbe42SPatrick Rudolph out:
637e6cbbe42SPatrick Rudolph 	mutex_unlock(&chip->i2c_lock);
638e6cbbe42SPatrick Rudolph 	return ret;
639e6cbbe42SPatrick Rudolph }
640e6cbbe42SPatrick Rudolph 
cy8c95x0_gpio_get_pincfg(struct cy8c95x0_pinctrl * chip,unsigned int off,unsigned long * config)641e6cbbe42SPatrick Rudolph static int cy8c95x0_gpio_get_pincfg(struct cy8c95x0_pinctrl *chip,
642e6cbbe42SPatrick Rudolph 				    unsigned int off,
643e6cbbe42SPatrick Rudolph 				    unsigned long *config)
644e6cbbe42SPatrick Rudolph {
645e6cbbe42SPatrick Rudolph 	enum pin_config_param param = pinconf_to_config_param(*config);
646e6cbbe42SPatrick Rudolph 	u8 port = cypress_get_port(chip, off);
647e6cbbe42SPatrick Rudolph 	u8 bit = cypress_get_pin_mask(chip, off);
648e6cbbe42SPatrick Rudolph 	unsigned int reg;
649e6cbbe42SPatrick Rudolph 	u32 reg_val;
650e6cbbe42SPatrick Rudolph 	u16 arg = 0;
651e6cbbe42SPatrick Rudolph 	int ret;
652e6cbbe42SPatrick Rudolph 
653e6cbbe42SPatrick Rudolph 	mutex_lock(&chip->i2c_lock);
654e6cbbe42SPatrick Rudolph 
65563e23304SAndy Shevchenko 	/* Select port */
656e6cbbe42SPatrick Rudolph 	ret = regmap_write(chip->regmap, CY8C95X0_PORTSEL, port);
657e6cbbe42SPatrick Rudolph 	if (ret < 0)
658e6cbbe42SPatrick Rudolph 		goto out;
659e6cbbe42SPatrick Rudolph 
660e6cbbe42SPatrick Rudolph 	switch (param) {
661e6cbbe42SPatrick Rudolph 	case PIN_CONFIG_BIAS_PULL_UP:
662e6cbbe42SPatrick Rudolph 		reg = CY8C95X0_DRV_PU;
663e6cbbe42SPatrick Rudolph 		break;
664e6cbbe42SPatrick Rudolph 	case PIN_CONFIG_BIAS_PULL_DOWN:
665e6cbbe42SPatrick Rudolph 		reg = CY8C95X0_DRV_PD;
666e6cbbe42SPatrick Rudolph 		break;
667e6cbbe42SPatrick Rudolph 	case PIN_CONFIG_BIAS_DISABLE:
668e6cbbe42SPatrick Rudolph 		reg = CY8C95X0_DRV_HIZ;
669e6cbbe42SPatrick Rudolph 		break;
670e6cbbe42SPatrick Rudolph 	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
671e6cbbe42SPatrick Rudolph 		reg = CY8C95X0_DRV_ODL;
672e6cbbe42SPatrick Rudolph 		break;
673e6cbbe42SPatrick Rudolph 	case PIN_CONFIG_DRIVE_OPEN_SOURCE:
674e6cbbe42SPatrick Rudolph 		reg = CY8C95X0_DRV_ODH;
675e6cbbe42SPatrick Rudolph 		break;
676e6cbbe42SPatrick Rudolph 	case PIN_CONFIG_DRIVE_PUSH_PULL:
677e6cbbe42SPatrick Rudolph 		reg = CY8C95X0_DRV_PP_FAST;
678e6cbbe42SPatrick Rudolph 		break;
679e6cbbe42SPatrick Rudolph 	case PIN_CONFIG_INPUT_ENABLE:
680e6cbbe42SPatrick Rudolph 		reg = CY8C95X0_DIRECTION;
681e6cbbe42SPatrick Rudolph 		break;
682e6cbbe42SPatrick Rudolph 	case PIN_CONFIG_MODE_PWM:
683e6cbbe42SPatrick Rudolph 		reg = CY8C95X0_PWMSEL;
684e6cbbe42SPatrick Rudolph 		break;
685e6cbbe42SPatrick Rudolph 	case PIN_CONFIG_OUTPUT:
686e6cbbe42SPatrick Rudolph 		reg = CY8C95X0_OUTPUT_(port);
687e6cbbe42SPatrick Rudolph 		break;
688e6cbbe42SPatrick Rudolph 	case PIN_CONFIG_OUTPUT_ENABLE:
689e6cbbe42SPatrick Rudolph 		reg = CY8C95X0_DIRECTION;
690e6cbbe42SPatrick Rudolph 		break;
691e6cbbe42SPatrick Rudolph 
692e6cbbe42SPatrick Rudolph 	case PIN_CONFIG_BIAS_HIGH_IMPEDANCE:
693e6cbbe42SPatrick Rudolph 	case PIN_CONFIG_BIAS_BUS_HOLD:
694e6cbbe42SPatrick Rudolph 	case PIN_CONFIG_BIAS_PULL_PIN_DEFAULT:
695e6cbbe42SPatrick Rudolph 	case PIN_CONFIG_DRIVE_STRENGTH:
696e6cbbe42SPatrick Rudolph 	case PIN_CONFIG_DRIVE_STRENGTH_UA:
697e6cbbe42SPatrick Rudolph 	case PIN_CONFIG_INPUT_DEBOUNCE:
698e6cbbe42SPatrick Rudolph 	case PIN_CONFIG_INPUT_SCHMITT:
699e6cbbe42SPatrick Rudolph 	case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
700e6cbbe42SPatrick Rudolph 	case PIN_CONFIG_MODE_LOW_POWER:
701e6cbbe42SPatrick Rudolph 	case PIN_CONFIG_PERSIST_STATE:
702e6cbbe42SPatrick Rudolph 	case PIN_CONFIG_POWER_SOURCE:
703e6cbbe42SPatrick Rudolph 	case PIN_CONFIG_SKEW_DELAY:
704e6cbbe42SPatrick Rudolph 	case PIN_CONFIG_SLEEP_HARDWARE_STATE:
705e6cbbe42SPatrick Rudolph 	case PIN_CONFIG_SLEW_RATE:
706e6cbbe42SPatrick Rudolph 	default:
707e6cbbe42SPatrick Rudolph 		ret = -ENOTSUPP;
708e6cbbe42SPatrick Rudolph 		goto out;
709e6cbbe42SPatrick Rudolph 	}
71063e23304SAndy Shevchenko 	/*
71163e23304SAndy Shevchenko 	 * Writing 1 to one of the drive mode registers will automatically
712e6cbbe42SPatrick Rudolph 	 * clear conflicting set bits in the other drive mode registers.
713e6cbbe42SPatrick Rudolph 	 */
714e6cbbe42SPatrick Rudolph 	ret = regmap_read(chip->regmap, reg, &reg_val);
715e6cbbe42SPatrick Rudolph 	if (reg_val & bit)
716e6cbbe42SPatrick Rudolph 		arg = 1;
717*406cea64SPatrick Rudolph 	if (param == PIN_CONFIG_OUTPUT_ENABLE)
718*406cea64SPatrick Rudolph 		arg = !arg;
719e6cbbe42SPatrick Rudolph 
720e6cbbe42SPatrick Rudolph 	*config = pinconf_to_config_packed(param, (u16)arg);
721e6cbbe42SPatrick Rudolph out:
722e6cbbe42SPatrick Rudolph 	mutex_unlock(&chip->i2c_lock);
723e6cbbe42SPatrick Rudolph 
724e6cbbe42SPatrick Rudolph 	return ret;
725e6cbbe42SPatrick Rudolph }
726e6cbbe42SPatrick Rudolph 
cy8c95x0_gpio_set_pincfg(struct cy8c95x0_pinctrl * chip,unsigned int off,unsigned long config)727e6cbbe42SPatrick Rudolph static int cy8c95x0_gpio_set_pincfg(struct cy8c95x0_pinctrl *chip,
728e6cbbe42SPatrick Rudolph 				    unsigned int off,
729e6cbbe42SPatrick Rudolph 				    unsigned long config)
730e6cbbe42SPatrick Rudolph {
731e6cbbe42SPatrick Rudolph 	u8 port = cypress_get_port(chip, off);
732e6cbbe42SPatrick Rudolph 	u8 bit = cypress_get_pin_mask(chip, off);
733e6cbbe42SPatrick Rudolph 	unsigned long param = pinconf_to_config_param(config);
7345f0a1661SPatrick Rudolph 	unsigned long arg = pinconf_to_config_argument(config);
735e6cbbe42SPatrick Rudolph 	unsigned int reg;
736e6cbbe42SPatrick Rudolph 	int ret;
737e6cbbe42SPatrick Rudolph 
738e6cbbe42SPatrick Rudolph 	mutex_lock(&chip->i2c_lock);
739e6cbbe42SPatrick Rudolph 
74063e23304SAndy Shevchenko 	/* Select port */
741e6cbbe42SPatrick Rudolph 	ret = regmap_write(chip->regmap, CY8C95X0_PORTSEL, port);
742e6cbbe42SPatrick Rudolph 	if (ret < 0)
743e6cbbe42SPatrick Rudolph 		goto out;
744e6cbbe42SPatrick Rudolph 
745e6cbbe42SPatrick Rudolph 	switch (param) {
746e6cbbe42SPatrick Rudolph 	case PIN_CONFIG_BIAS_PULL_UP:
747d6afdf88SAndy Shevchenko 		__clear_bit(off, chip->push_pull);
748e6cbbe42SPatrick Rudolph 		reg = CY8C95X0_DRV_PU;
749e6cbbe42SPatrick Rudolph 		break;
750e6cbbe42SPatrick Rudolph 	case PIN_CONFIG_BIAS_PULL_DOWN:
751d6afdf88SAndy Shevchenko 		__clear_bit(off, chip->push_pull);
752e6cbbe42SPatrick Rudolph 		reg = CY8C95X0_DRV_PD;
753e6cbbe42SPatrick Rudolph 		break;
754e6cbbe42SPatrick Rudolph 	case PIN_CONFIG_BIAS_DISABLE:
755d6afdf88SAndy Shevchenko 		__clear_bit(off, chip->push_pull);
756e6cbbe42SPatrick Rudolph 		reg = CY8C95X0_DRV_HIZ;
757e6cbbe42SPatrick Rudolph 		break;
758e6cbbe42SPatrick Rudolph 	case PIN_CONFIG_DRIVE_OPEN_DRAIN:
759d6afdf88SAndy Shevchenko 		__clear_bit(off, chip->push_pull);
760e6cbbe42SPatrick Rudolph 		reg = CY8C95X0_DRV_ODL;
761e6cbbe42SPatrick Rudolph 		break;
762e6cbbe42SPatrick Rudolph 	case PIN_CONFIG_DRIVE_OPEN_SOURCE:
763d6afdf88SAndy Shevchenko 		__clear_bit(off, chip->push_pull);
764e6cbbe42SPatrick Rudolph 		reg = CY8C95X0_DRV_ODH;
765e6cbbe42SPatrick Rudolph 		break;
766e6cbbe42SPatrick Rudolph 	case PIN_CONFIG_DRIVE_PUSH_PULL:
767d6afdf88SAndy Shevchenko 		__set_bit(off, chip->push_pull);
768e6cbbe42SPatrick Rudolph 		reg = CY8C95X0_DRV_PP_FAST;
769e6cbbe42SPatrick Rudolph 		break;
770e6cbbe42SPatrick Rudolph 	case PIN_CONFIG_MODE_PWM:
771e6cbbe42SPatrick Rudolph 		reg = CY8C95X0_PWMSEL;
772e6cbbe42SPatrick Rudolph 		break;
7735f0a1661SPatrick Rudolph 	case PIN_CONFIG_OUTPUT_ENABLE:
7745f0a1661SPatrick Rudolph 		ret = cy8c95x0_pinmux_direction(chip, off, !arg);
7755f0a1661SPatrick Rudolph 		goto out;
7765f0a1661SPatrick Rudolph 	case PIN_CONFIG_INPUT_ENABLE:
7775f0a1661SPatrick Rudolph 		ret = cy8c95x0_pinmux_direction(chip, off, arg);
7785f0a1661SPatrick Rudolph 		goto out;
779e6cbbe42SPatrick Rudolph 	default:
780e6cbbe42SPatrick Rudolph 		ret = -ENOTSUPP;
781e6cbbe42SPatrick Rudolph 		goto out;
782e6cbbe42SPatrick Rudolph 	}
78363e23304SAndy Shevchenko 	/*
78463e23304SAndy Shevchenko 	 * Writing 1 to one of the drive mode registers will automatically
785e6cbbe42SPatrick Rudolph 	 * clear conflicting set bits in the other drive mode registers.
786e6cbbe42SPatrick Rudolph 	 */
787e6cbbe42SPatrick Rudolph 	ret = regmap_write_bits(chip->regmap, reg, bit, bit);
788e6cbbe42SPatrick Rudolph 
789e6cbbe42SPatrick Rudolph out:
790e6cbbe42SPatrick Rudolph 	mutex_unlock(&chip->i2c_lock);
791e6cbbe42SPatrick Rudolph 	return ret;
792e6cbbe42SPatrick Rudolph }
793e6cbbe42SPatrick Rudolph 
cy8c95x0_gpio_get_multiple(struct gpio_chip * gc,unsigned long * mask,unsigned long * bits)794e6cbbe42SPatrick Rudolph static int cy8c95x0_gpio_get_multiple(struct gpio_chip *gc,
795e6cbbe42SPatrick Rudolph 				      unsigned long *mask, unsigned long *bits)
796e6cbbe42SPatrick Rudolph {
797e6cbbe42SPatrick Rudolph 	struct cy8c95x0_pinctrl *chip = gpiochip_get_data(gc);
798e6cbbe42SPatrick Rudolph 
799e6cbbe42SPatrick Rudolph 	return cy8c95x0_read_regs_mask(chip, CY8C95X0_INPUT, bits, mask);
800e6cbbe42SPatrick Rudolph }
801e6cbbe42SPatrick Rudolph 
cy8c95x0_gpio_set_multiple(struct gpio_chip * gc,unsigned long * mask,unsigned long * bits)802e6cbbe42SPatrick Rudolph static void cy8c95x0_gpio_set_multiple(struct gpio_chip *gc,
803e6cbbe42SPatrick Rudolph 				       unsigned long *mask, unsigned long *bits)
804e6cbbe42SPatrick Rudolph {
805e6cbbe42SPatrick Rudolph 	struct cy8c95x0_pinctrl *chip = gpiochip_get_data(gc);
806e6cbbe42SPatrick Rudolph 
807e6cbbe42SPatrick Rudolph 	cy8c95x0_write_regs_mask(chip, CY8C95X0_OUTPUT, bits, mask);
808e6cbbe42SPatrick Rudolph }
809e6cbbe42SPatrick Rudolph 
cy8c95x0_add_pin_ranges(struct gpio_chip * gc)810d86e0344SAndy Shevchenko static int cy8c95x0_add_pin_ranges(struct gpio_chip *gc)
811d86e0344SAndy Shevchenko {
812d86e0344SAndy Shevchenko 	struct cy8c95x0_pinctrl *chip = gpiochip_get_data(gc);
813d86e0344SAndy Shevchenko 	struct device *dev = chip->dev;
814d86e0344SAndy Shevchenko 	int ret;
815d86e0344SAndy Shevchenko 
816d86e0344SAndy Shevchenko 	ret = gpiochip_add_pin_range(gc, dev_name(dev), 0, 0, chip->tpin);
817d86e0344SAndy Shevchenko 	if (ret)
818d86e0344SAndy Shevchenko 		dev_err(dev, "failed to add GPIO pin range\n");
819d86e0344SAndy Shevchenko 
820d86e0344SAndy Shevchenko 	return ret;
821d86e0344SAndy Shevchenko }
822d86e0344SAndy Shevchenko 
cy8c95x0_setup_gpiochip(struct cy8c95x0_pinctrl * chip)823d86e0344SAndy Shevchenko static int cy8c95x0_setup_gpiochip(struct cy8c95x0_pinctrl *chip)
824e6cbbe42SPatrick Rudolph {
825e6cbbe42SPatrick Rudolph 	struct gpio_chip *gc = &chip->gpio_chip;
826e6cbbe42SPatrick Rudolph 
827a039dfb9SAndy Shevchenko 	gc->request = gpiochip_generic_request;
828a039dfb9SAndy Shevchenko 	gc->free = gpiochip_generic_free;
829e6cbbe42SPatrick Rudolph 	gc->direction_input  = cy8c95x0_gpio_direction_input;
830e6cbbe42SPatrick Rudolph 	gc->direction_output = cy8c95x0_gpio_direction_output;
831e6cbbe42SPatrick Rudolph 	gc->get = cy8c95x0_gpio_get_value;
832e6cbbe42SPatrick Rudolph 	gc->set = cy8c95x0_gpio_set_value;
833e6cbbe42SPatrick Rudolph 	gc->get_direction = cy8c95x0_gpio_get_direction;
834e6cbbe42SPatrick Rudolph 	gc->get_multiple = cy8c95x0_gpio_get_multiple;
835e6cbbe42SPatrick Rudolph 	gc->set_multiple = cy8c95x0_gpio_set_multiple;
8363d5729d5SPatrick Rudolph 	gc->set_config = gpiochip_generic_config;
837e6cbbe42SPatrick Rudolph 	gc->can_sleep = true;
838d86e0344SAndy Shevchenko 	gc->add_pin_ranges = cy8c95x0_add_pin_ranges;
839e6cbbe42SPatrick Rudolph 
840e6cbbe42SPatrick Rudolph 	gc->base = -1;
841d86e0344SAndy Shevchenko 	gc->ngpio = chip->tpin;
842e6cbbe42SPatrick Rudolph 
843e6cbbe42SPatrick Rudolph 	gc->parent = chip->dev;
844e6cbbe42SPatrick Rudolph 	gc->owner = THIS_MODULE;
845e6cbbe42SPatrick Rudolph 	gc->names = NULL;
846e6cbbe42SPatrick Rudolph 
847e6cbbe42SPatrick Rudolph 	gc->label = dev_name(chip->dev);
848e6cbbe42SPatrick Rudolph 
849e6cbbe42SPatrick Rudolph 	return devm_gpiochip_add_data(chip->dev, gc, chip);
850e6cbbe42SPatrick Rudolph }
851e6cbbe42SPatrick Rudolph 
cy8c95x0_irq_mask(struct irq_data * d)852e6cbbe42SPatrick Rudolph static void cy8c95x0_irq_mask(struct irq_data *d)
853e6cbbe42SPatrick Rudolph {
854e6cbbe42SPatrick Rudolph 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
855e6cbbe42SPatrick Rudolph 	struct cy8c95x0_pinctrl *chip = gpiochip_get_data(gc);
856f5d62025SAndy Shevchenko 	irq_hw_number_t hwirq = irqd_to_hwirq(d);
857e6cbbe42SPatrick Rudolph 
858f5d62025SAndy Shevchenko 	set_bit(hwirq, chip->irq_mask);
859f5d62025SAndy Shevchenko 	gpiochip_disable_irq(gc, hwirq);
860e6cbbe42SPatrick Rudolph }
861e6cbbe42SPatrick Rudolph 
cy8c95x0_irq_unmask(struct irq_data * d)862e6cbbe42SPatrick Rudolph static void cy8c95x0_irq_unmask(struct irq_data *d)
863e6cbbe42SPatrick Rudolph {
864e6cbbe42SPatrick Rudolph 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
865e6cbbe42SPatrick Rudolph 	struct cy8c95x0_pinctrl *chip = gpiochip_get_data(gc);
866f5d62025SAndy Shevchenko 	irq_hw_number_t hwirq = irqd_to_hwirq(d);
867e6cbbe42SPatrick Rudolph 
868f5d62025SAndy Shevchenko 	gpiochip_enable_irq(gc, hwirq);
869f5d62025SAndy Shevchenko 	clear_bit(hwirq, chip->irq_mask);
870e6cbbe42SPatrick Rudolph }
871e6cbbe42SPatrick Rudolph 
cy8c95x0_irq_bus_lock(struct irq_data * d)872e6cbbe42SPatrick Rudolph static void cy8c95x0_irq_bus_lock(struct irq_data *d)
873e6cbbe42SPatrick Rudolph {
874e6cbbe42SPatrick Rudolph 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
875e6cbbe42SPatrick Rudolph 	struct cy8c95x0_pinctrl *chip = gpiochip_get_data(gc);
876e6cbbe42SPatrick Rudolph 
877e6cbbe42SPatrick Rudolph 	mutex_lock(&chip->irq_lock);
878e6cbbe42SPatrick Rudolph }
879e6cbbe42SPatrick Rudolph 
cy8c95x0_irq_bus_sync_unlock(struct irq_data * d)880e6cbbe42SPatrick Rudolph static void cy8c95x0_irq_bus_sync_unlock(struct irq_data *d)
881e6cbbe42SPatrick Rudolph {
882e6cbbe42SPatrick Rudolph 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
883e6cbbe42SPatrick Rudolph 	struct cy8c95x0_pinctrl *chip = gpiochip_get_data(gc);
884e6cbbe42SPatrick Rudolph 	DECLARE_BITMAP(ones, MAX_LINE);
885e6cbbe42SPatrick Rudolph 	DECLARE_BITMAP(irq_mask, MAX_LINE);
886e6cbbe42SPatrick Rudolph 	DECLARE_BITMAP(reg_direction, MAX_LINE);
887e6cbbe42SPatrick Rudolph 
888e6cbbe42SPatrick Rudolph 	bitmap_fill(ones, MAX_LINE);
889e6cbbe42SPatrick Rudolph 
890e6cbbe42SPatrick Rudolph 	cy8c95x0_write_regs_mask(chip, CY8C95X0_INTMASK, chip->irq_mask, ones);
891e6cbbe42SPatrick Rudolph 
892e6cbbe42SPatrick Rudolph 	/* Switch direction to input if needed */
893e6cbbe42SPatrick Rudolph 	cy8c95x0_read_regs_mask(chip, CY8C95X0_DIRECTION, reg_direction, chip->irq_mask);
894e6cbbe42SPatrick Rudolph 	bitmap_or(irq_mask, chip->irq_mask, reg_direction, MAX_LINE);
895e6cbbe42SPatrick Rudolph 	bitmap_complement(irq_mask, irq_mask, MAX_LINE);
896e6cbbe42SPatrick Rudolph 
897e6cbbe42SPatrick Rudolph 	/* Look for any newly setup interrupt */
898e6cbbe42SPatrick Rudolph 	cy8c95x0_write_regs_mask(chip, CY8C95X0_DIRECTION, ones, irq_mask);
899e6cbbe42SPatrick Rudolph 
900e6cbbe42SPatrick Rudolph 	mutex_unlock(&chip->irq_lock);
901e6cbbe42SPatrick Rudolph }
902e6cbbe42SPatrick Rudolph 
cy8c95x0_irq_set_type(struct irq_data * d,unsigned int type)903e6cbbe42SPatrick Rudolph static int cy8c95x0_irq_set_type(struct irq_data *d, unsigned int type)
904e6cbbe42SPatrick Rudolph {
905e6cbbe42SPatrick Rudolph 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
906e6cbbe42SPatrick Rudolph 	struct cy8c95x0_pinctrl *chip = gpiochip_get_data(gc);
907e6cbbe42SPatrick Rudolph 	irq_hw_number_t hwirq = irqd_to_hwirq(d);
908e6cbbe42SPatrick Rudolph 	unsigned int trig_type;
909e6cbbe42SPatrick Rudolph 
910e6cbbe42SPatrick Rudolph 	switch (type) {
911e6cbbe42SPatrick Rudolph 	case IRQ_TYPE_EDGE_RISING:
912e6cbbe42SPatrick Rudolph 	case IRQ_TYPE_EDGE_FALLING:
913e6cbbe42SPatrick Rudolph 	case IRQ_TYPE_EDGE_BOTH:
914e6cbbe42SPatrick Rudolph 		trig_type = type;
915e6cbbe42SPatrick Rudolph 		break;
916e6cbbe42SPatrick Rudolph 	case IRQ_TYPE_LEVEL_HIGH:
917e6cbbe42SPatrick Rudolph 		trig_type = IRQ_TYPE_EDGE_RISING;
918e6cbbe42SPatrick Rudolph 		break;
919e6cbbe42SPatrick Rudolph 	case IRQ_TYPE_LEVEL_LOW:
920e6cbbe42SPatrick Rudolph 		trig_type = IRQ_TYPE_EDGE_FALLING;
921e6cbbe42SPatrick Rudolph 		break;
922e6cbbe42SPatrick Rudolph 	default:
923e6cbbe42SPatrick Rudolph 		dev_err(chip->dev, "irq %d: unsupported type %d\n", d->irq, type);
924e6cbbe42SPatrick Rudolph 		return -EINVAL;
925e6cbbe42SPatrick Rudolph 	}
926e6cbbe42SPatrick Rudolph 
927e6cbbe42SPatrick Rudolph 	assign_bit(hwirq, chip->irq_trig_fall, trig_type & IRQ_TYPE_EDGE_FALLING);
928e6cbbe42SPatrick Rudolph 	assign_bit(hwirq, chip->irq_trig_raise, trig_type & IRQ_TYPE_EDGE_RISING);
929e6cbbe42SPatrick Rudolph 	assign_bit(hwirq, chip->irq_trig_low, type == IRQ_TYPE_LEVEL_LOW);
930e6cbbe42SPatrick Rudolph 	assign_bit(hwirq, chip->irq_trig_high, type == IRQ_TYPE_LEVEL_HIGH);
931e6cbbe42SPatrick Rudolph 
932e6cbbe42SPatrick Rudolph 	return 0;
933e6cbbe42SPatrick Rudolph }
934e6cbbe42SPatrick Rudolph 
cy8c95x0_irq_shutdown(struct irq_data * d)935e6cbbe42SPatrick Rudolph static void cy8c95x0_irq_shutdown(struct irq_data *d)
936e6cbbe42SPatrick Rudolph {
937e6cbbe42SPatrick Rudolph 	struct gpio_chip *gc = irq_data_get_irq_chip_data(d);
938e6cbbe42SPatrick Rudolph 	struct cy8c95x0_pinctrl *chip = gpiochip_get_data(gc);
939e6cbbe42SPatrick Rudolph 	irq_hw_number_t hwirq = irqd_to_hwirq(d);
940e6cbbe42SPatrick Rudolph 
941e6cbbe42SPatrick Rudolph 	clear_bit(hwirq, chip->irq_trig_raise);
942e6cbbe42SPatrick Rudolph 	clear_bit(hwirq, chip->irq_trig_fall);
943e6cbbe42SPatrick Rudolph 	clear_bit(hwirq, chip->irq_trig_low);
944e6cbbe42SPatrick Rudolph 	clear_bit(hwirq, chip->irq_trig_high);
945e6cbbe42SPatrick Rudolph }
946e6cbbe42SPatrick Rudolph 
947f5d62025SAndy Shevchenko static const struct irq_chip cy8c95x0_irqchip = {
948f5d62025SAndy Shevchenko 	.name = "cy8c95x0-irq",
949f5d62025SAndy Shevchenko 	.irq_mask = cy8c95x0_irq_mask,
950f5d62025SAndy Shevchenko 	.irq_unmask = cy8c95x0_irq_unmask,
951f5d62025SAndy Shevchenko 	.irq_bus_lock = cy8c95x0_irq_bus_lock,
952f5d62025SAndy Shevchenko 	.irq_bus_sync_unlock = cy8c95x0_irq_bus_sync_unlock,
953f5d62025SAndy Shevchenko 	.irq_set_type = cy8c95x0_irq_set_type,
954f5d62025SAndy Shevchenko 	.irq_shutdown = cy8c95x0_irq_shutdown,
955f5d62025SAndy Shevchenko 	.flags = IRQCHIP_IMMUTABLE,
956f5d62025SAndy Shevchenko 	GPIOCHIP_IRQ_RESOURCE_HELPERS,
957f5d62025SAndy Shevchenko };
958f5d62025SAndy Shevchenko 
cy8c95x0_irq_pending(struct cy8c95x0_pinctrl * chip,unsigned long * pending)959e6cbbe42SPatrick Rudolph static bool cy8c95x0_irq_pending(struct cy8c95x0_pinctrl *chip, unsigned long *pending)
960e6cbbe42SPatrick Rudolph {
961e6cbbe42SPatrick Rudolph 	DECLARE_BITMAP(ones, MAX_LINE);
962e6cbbe42SPatrick Rudolph 	DECLARE_BITMAP(cur_stat, MAX_LINE);
963e6cbbe42SPatrick Rudolph 	DECLARE_BITMAP(new_stat, MAX_LINE);
964e6cbbe42SPatrick Rudolph 	DECLARE_BITMAP(trigger, MAX_LINE);
965e6cbbe42SPatrick Rudolph 
966e6cbbe42SPatrick Rudolph 	bitmap_fill(ones, MAX_LINE);
967e6cbbe42SPatrick Rudolph 
968e6cbbe42SPatrick Rudolph 	/* Read the current interrupt status from the device */
969e6cbbe42SPatrick Rudolph 	if (cy8c95x0_read_regs_mask(chip, CY8C95X0_INTSTATUS, trigger, ones))
970e6cbbe42SPatrick Rudolph 		return false;
971e6cbbe42SPatrick Rudolph 
972e6cbbe42SPatrick Rudolph 	/* Check latched inputs */
973e6cbbe42SPatrick Rudolph 	if (cy8c95x0_read_regs_mask(chip, CY8C95X0_INPUT, cur_stat, trigger))
974e6cbbe42SPatrick Rudolph 		return false;
975e6cbbe42SPatrick Rudolph 
976e6cbbe42SPatrick Rudolph 	/* Apply filter for rising/falling edge selection */
977e6cbbe42SPatrick Rudolph 	bitmap_replace(new_stat, chip->irq_trig_fall, chip->irq_trig_raise,
978e6cbbe42SPatrick Rudolph 		       cur_stat, MAX_LINE);
979e6cbbe42SPatrick Rudolph 
980e6cbbe42SPatrick Rudolph 	bitmap_and(pending, new_stat, trigger, MAX_LINE);
981e6cbbe42SPatrick Rudolph 
982e6cbbe42SPatrick Rudolph 	return !bitmap_empty(pending, MAX_LINE);
983e6cbbe42SPatrick Rudolph }
984e6cbbe42SPatrick Rudolph 
cy8c95x0_irq_handler(int irq,void * devid)985e6cbbe42SPatrick Rudolph static irqreturn_t cy8c95x0_irq_handler(int irq, void *devid)
986e6cbbe42SPatrick Rudolph {
987e6cbbe42SPatrick Rudolph 	struct cy8c95x0_pinctrl *chip = devid;
988e6cbbe42SPatrick Rudolph 	struct gpio_chip *gc = &chip->gpio_chip;
989e6cbbe42SPatrick Rudolph 	DECLARE_BITMAP(pending, MAX_LINE);
990e6cbbe42SPatrick Rudolph 	int nested_irq, level;
991e6cbbe42SPatrick Rudolph 	bool ret;
992e6cbbe42SPatrick Rudolph 
993e6cbbe42SPatrick Rudolph 	ret = cy8c95x0_irq_pending(chip, pending);
994e6cbbe42SPatrick Rudolph 	if (!ret)
995e6cbbe42SPatrick Rudolph 		return IRQ_RETVAL(0);
996e6cbbe42SPatrick Rudolph 
997e6cbbe42SPatrick Rudolph 	ret = 0;
998e6cbbe42SPatrick Rudolph 	for_each_set_bit(level, pending, MAX_LINE) {
999e6cbbe42SPatrick Rudolph 		/* Already accounted for 4bit gap in GPort2 */
1000e6cbbe42SPatrick Rudolph 		nested_irq = irq_find_mapping(gc->irq.domain, level);
1001e6cbbe42SPatrick Rudolph 
1002e6cbbe42SPatrick Rudolph 		if (unlikely(nested_irq <= 0)) {
1003e6cbbe42SPatrick Rudolph 			dev_warn_ratelimited(gc->parent, "unmapped interrupt %d\n", level);
1004e6cbbe42SPatrick Rudolph 			continue;
1005e6cbbe42SPatrick Rudolph 		}
1006e6cbbe42SPatrick Rudolph 
1007e6cbbe42SPatrick Rudolph 		if (test_bit(level, chip->irq_trig_low))
1008e6cbbe42SPatrick Rudolph 			while (!cy8c95x0_gpio_get_value(gc, level))
1009e6cbbe42SPatrick Rudolph 				handle_nested_irq(nested_irq);
1010e6cbbe42SPatrick Rudolph 		else if (test_bit(level, chip->irq_trig_high))
1011e6cbbe42SPatrick Rudolph 			while (cy8c95x0_gpio_get_value(gc, level))
1012e6cbbe42SPatrick Rudolph 				handle_nested_irq(nested_irq);
1013e6cbbe42SPatrick Rudolph 		else
1014e6cbbe42SPatrick Rudolph 			handle_nested_irq(nested_irq);
1015e6cbbe42SPatrick Rudolph 
1016e6cbbe42SPatrick Rudolph 		ret = 1;
1017e6cbbe42SPatrick Rudolph 	}
1018e6cbbe42SPatrick Rudolph 
1019e6cbbe42SPatrick Rudolph 	return IRQ_RETVAL(ret);
1020e6cbbe42SPatrick Rudolph }
1021e6cbbe42SPatrick Rudolph 
cy8c95x0_pinctrl_get_groups_count(struct pinctrl_dev * pctldev)1022e6cbbe42SPatrick Rudolph static int cy8c95x0_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
1023e6cbbe42SPatrick Rudolph {
1024e6cbbe42SPatrick Rudolph 	struct cy8c95x0_pinctrl *chip = pinctrl_dev_get_drvdata(pctldev);
1025e6cbbe42SPatrick Rudolph 
1026e6cbbe42SPatrick Rudolph 	return chip->tpin;
1027e6cbbe42SPatrick Rudolph }
1028e6cbbe42SPatrick Rudolph 
cy8c95x0_pinctrl_get_group_name(struct pinctrl_dev * pctldev,unsigned int group)1029e6cbbe42SPatrick Rudolph static const char *cy8c95x0_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
1030e6cbbe42SPatrick Rudolph 						   unsigned int group)
1031e6cbbe42SPatrick Rudolph {
1032e6cbbe42SPatrick Rudolph 	return cy8c95x0_groups[group];
1033e6cbbe42SPatrick Rudolph }
1034e6cbbe42SPatrick Rudolph 
cy8c95x0_pinctrl_get_group_pins(struct pinctrl_dev * pctldev,unsigned int group,const unsigned int ** pins,unsigned int * num_pins)1035e6cbbe42SPatrick Rudolph static int cy8c95x0_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
1036e6cbbe42SPatrick Rudolph 					   unsigned int group,
1037e6cbbe42SPatrick Rudolph 					   const unsigned int **pins,
1038e6cbbe42SPatrick Rudolph 					   unsigned int *num_pins)
1039e6cbbe42SPatrick Rudolph {
1040e6cbbe42SPatrick Rudolph 	*pins = &cy8c9560_pins[group].number;
1041e6cbbe42SPatrick Rudolph 	*num_pins = 1;
1042e6cbbe42SPatrick Rudolph 	return 0;
1043e6cbbe42SPatrick Rudolph }
1044e6cbbe42SPatrick Rudolph 
cy8c95x0_get_fname(unsigned int selector)1045f12352f3SAndy Shevchenko static const char *cy8c95x0_get_fname(unsigned int selector)
1046f12352f3SAndy Shevchenko {
1047f12352f3SAndy Shevchenko 	if (selector == 0)
1048f12352f3SAndy Shevchenko 		return "gpio";
1049f12352f3SAndy Shevchenko 	else
1050f12352f3SAndy Shevchenko 		return "pwm";
1051f12352f3SAndy Shevchenko }
1052f12352f3SAndy Shevchenko 
cy8c95x0_pin_dbg_show(struct pinctrl_dev * pctldev,struct seq_file * s,unsigned int pin)1053f12352f3SAndy Shevchenko static void cy8c95x0_pin_dbg_show(struct pinctrl_dev *pctldev, struct seq_file *s,
1054f12352f3SAndy Shevchenko 				  unsigned int pin)
1055f12352f3SAndy Shevchenko {
1056f12352f3SAndy Shevchenko 	struct cy8c95x0_pinctrl *chip = pinctrl_dev_get_drvdata(pctldev);
1057f12352f3SAndy Shevchenko 	DECLARE_BITMAP(mask, MAX_LINE);
1058f12352f3SAndy Shevchenko 	DECLARE_BITMAP(pwm, MAX_LINE);
1059f12352f3SAndy Shevchenko 
1060f12352f3SAndy Shevchenko 	bitmap_zero(mask, MAX_LINE);
1061f12352f3SAndy Shevchenko 	__set_bit(pin, mask);
1062f12352f3SAndy Shevchenko 
1063f12352f3SAndy Shevchenko 	if (cy8c95x0_read_regs_mask(chip, CY8C95X0_PWMSEL, pwm, mask)) {
1064f12352f3SAndy Shevchenko 		seq_puts(s, "not available");
1065f12352f3SAndy Shevchenko 		return;
1066f12352f3SAndy Shevchenko 	}
1067f12352f3SAndy Shevchenko 
1068f12352f3SAndy Shevchenko 	seq_printf(s, "MODE:%s", cy8c95x0_get_fname(test_bit(pin, pwm)));
1069f12352f3SAndy Shevchenko }
1070f12352f3SAndy Shevchenko 
1071e6cbbe42SPatrick Rudolph static const struct pinctrl_ops cy8c95x0_pinctrl_ops = {
1072e6cbbe42SPatrick Rudolph 	.get_groups_count = cy8c95x0_pinctrl_get_groups_count,
1073e6cbbe42SPatrick Rudolph 	.get_group_name = cy8c95x0_pinctrl_get_group_name,
1074e6cbbe42SPatrick Rudolph 	.get_group_pins = cy8c95x0_pinctrl_get_group_pins,
10758586466eSAndy Shevchenko #ifdef CONFIG_OF
1076e6cbbe42SPatrick Rudolph 	.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
1077e6cbbe42SPatrick Rudolph 	.dt_free_map = pinconf_generic_dt_free_map,
10788586466eSAndy Shevchenko #endif
1079f12352f3SAndy Shevchenko 	.pin_dbg_show = cy8c95x0_pin_dbg_show,
1080e6cbbe42SPatrick Rudolph };
1081e6cbbe42SPatrick Rudolph 
cy8c95x0_get_function_name(struct pinctrl_dev * pctldev,unsigned int selector)1082ee6cac37SAndy Shevchenko static const char *cy8c95x0_get_function_name(struct pinctrl_dev *pctldev, unsigned int selector)
1083f12352f3SAndy Shevchenko {
1084f12352f3SAndy Shevchenko 	return cy8c95x0_get_fname(selector);
1085f12352f3SAndy Shevchenko }
1086f12352f3SAndy Shevchenko 
cy8c95x0_get_functions_count(struct pinctrl_dev * pctldev)1087e6cbbe42SPatrick Rudolph static int cy8c95x0_get_functions_count(struct pinctrl_dev *pctldev)
1088e6cbbe42SPatrick Rudolph {
1089e6cbbe42SPatrick Rudolph 	return 2;
1090e6cbbe42SPatrick Rudolph }
1091e6cbbe42SPatrick Rudolph 
cy8c95x0_get_function_groups(struct pinctrl_dev * pctldev,unsigned int selector,const char * const ** groups,unsigned int * const num_groups)1092ee6cac37SAndy Shevchenko static int cy8c95x0_get_function_groups(struct pinctrl_dev *pctldev, unsigned int selector,
1093e6cbbe42SPatrick Rudolph 					const char * const **groups,
1094e6cbbe42SPatrick Rudolph 					unsigned int * const num_groups)
1095e6cbbe42SPatrick Rudolph {
1096e6cbbe42SPatrick Rudolph 	struct cy8c95x0_pinctrl *chip = pinctrl_dev_get_drvdata(pctldev);
1097e6cbbe42SPatrick Rudolph 
1098e6cbbe42SPatrick Rudolph 	*groups = cy8c95x0_groups;
1099e6cbbe42SPatrick Rudolph 	*num_groups = chip->tpin;
1100e6cbbe42SPatrick Rudolph 	return 0;
1101e6cbbe42SPatrick Rudolph }
1102e6cbbe42SPatrick Rudolph 
cy8c95x0_set_mode(struct cy8c95x0_pinctrl * chip,unsigned int off,bool mode)11039b3148d6SAndy Shevchenko static int cy8c95x0_set_mode(struct cy8c95x0_pinctrl *chip, unsigned int off, bool mode)
1104e6cbbe42SPatrick Rudolph {
1105e6cbbe42SPatrick Rudolph 	u8 port = cypress_get_port(chip, off);
1106e6cbbe42SPatrick Rudolph 	u8 bit = cypress_get_pin_mask(chip, off);
1107e6cbbe42SPatrick Rudolph 	int ret;
1108e6cbbe42SPatrick Rudolph 
110963e23304SAndy Shevchenko 	/* Select port */
1110e6cbbe42SPatrick Rudolph 	ret = regmap_write(chip->regmap, CY8C95X0_PORTSEL, port);
1111e6cbbe42SPatrick Rudolph 	if (ret < 0)
1112e6cbbe42SPatrick Rudolph 		return ret;
1113e6cbbe42SPatrick Rudolph 
11149b3148d6SAndy Shevchenko 	return regmap_write_bits(chip->regmap, CY8C95X0_PWMSEL, bit, mode ? bit : 0);
11159b3148d6SAndy Shevchenko }
11169b3148d6SAndy Shevchenko 
cy8c95x0_pinmux_mode(struct cy8c95x0_pinctrl * chip,unsigned int selector,unsigned int group)11179b3148d6SAndy Shevchenko static int cy8c95x0_pinmux_mode(struct cy8c95x0_pinctrl *chip,
11189b3148d6SAndy Shevchenko 				unsigned int selector, unsigned int group)
11199b3148d6SAndy Shevchenko {
11209b3148d6SAndy Shevchenko 	u8 port = cypress_get_port(chip, group);
11219b3148d6SAndy Shevchenko 	u8 bit = cypress_get_pin_mask(chip, group);
11229b3148d6SAndy Shevchenko 	int ret;
11239b3148d6SAndy Shevchenko 
1124417c3260SAndy Shevchenko 	ret = cy8c95x0_set_mode(chip, group, selector);
1125e6cbbe42SPatrick Rudolph 	if (ret < 0)
1126e6cbbe42SPatrick Rudolph 		return ret;
1127e6cbbe42SPatrick Rudolph 
1128417c3260SAndy Shevchenko 	if (selector == 0)
1129417c3260SAndy Shevchenko 		return 0;
1130417c3260SAndy Shevchenko 
1131e6cbbe42SPatrick Rudolph 	/* Set direction to output & set output to 1 so that PWM can work */
1132e6cbbe42SPatrick Rudolph 	ret = regmap_write_bits(chip->regmap, CY8C95X0_DIRECTION, bit, bit);
1133e6cbbe42SPatrick Rudolph 	if (ret < 0)
1134e6cbbe42SPatrick Rudolph 		return ret;
1135e6cbbe42SPatrick Rudolph 
1136e6cbbe42SPatrick Rudolph 	return regmap_write_bits(chip->regmap, CY8C95X0_OUTPUT_(port), bit, bit);
1137e6cbbe42SPatrick Rudolph }
1138e6cbbe42SPatrick Rudolph 
cy8c95x0_set_mux(struct pinctrl_dev * pctldev,unsigned int selector,unsigned int group)1139e6cbbe42SPatrick Rudolph static int cy8c95x0_set_mux(struct pinctrl_dev *pctldev, unsigned int selector,
1140e6cbbe42SPatrick Rudolph 			    unsigned int group)
1141e6cbbe42SPatrick Rudolph {
1142e6cbbe42SPatrick Rudolph 	struct cy8c95x0_pinctrl *chip = pinctrl_dev_get_drvdata(pctldev);
114356e380cfSAndy Shevchenko 	int ret;
1144e6cbbe42SPatrick Rudolph 
114556e380cfSAndy Shevchenko 	mutex_lock(&chip->i2c_lock);
11469b3148d6SAndy Shevchenko 	ret = cy8c95x0_pinmux_mode(chip, selector, group);
114756e380cfSAndy Shevchenko 	mutex_unlock(&chip->i2c_lock);
114856e380cfSAndy Shevchenko 
114956e380cfSAndy Shevchenko 	return ret;
1150e6cbbe42SPatrick Rudolph }
1151e6cbbe42SPatrick Rudolph 
cy8c95x0_gpio_request_enable(struct pinctrl_dev * pctldev,struct pinctrl_gpio_range * range,unsigned int pin)1152a039dfb9SAndy Shevchenko static int cy8c95x0_gpio_request_enable(struct pinctrl_dev *pctldev,
1153a039dfb9SAndy Shevchenko 					struct pinctrl_gpio_range *range,
1154a039dfb9SAndy Shevchenko 					unsigned int pin)
1155a039dfb9SAndy Shevchenko {
1156a039dfb9SAndy Shevchenko 	struct cy8c95x0_pinctrl *chip = pinctrl_dev_get_drvdata(pctldev);
1157a039dfb9SAndy Shevchenko 	int ret;
1158a039dfb9SAndy Shevchenko 
1159a039dfb9SAndy Shevchenko 	mutex_lock(&chip->i2c_lock);
1160a039dfb9SAndy Shevchenko 	ret = cy8c95x0_set_mode(chip, pin, false);
1161a039dfb9SAndy Shevchenko 	mutex_unlock(&chip->i2c_lock);
1162a039dfb9SAndy Shevchenko 
1163a039dfb9SAndy Shevchenko 	return ret;
1164a039dfb9SAndy Shevchenko }
1165a039dfb9SAndy Shevchenko 
cy8c95x0_pinmux_direction(struct cy8c95x0_pinctrl * chip,unsigned int pin,bool input)1166a039dfb9SAndy Shevchenko static int cy8c95x0_pinmux_direction(struct cy8c95x0_pinctrl *chip,
1167a039dfb9SAndy Shevchenko 				     unsigned int pin, bool input)
1168a039dfb9SAndy Shevchenko {
1169a039dfb9SAndy Shevchenko 	u8 port = cypress_get_port(chip, pin);
1170a039dfb9SAndy Shevchenko 	u8 bit = cypress_get_pin_mask(chip, pin);
1171a039dfb9SAndy Shevchenko 	int ret;
1172a039dfb9SAndy Shevchenko 
1173a039dfb9SAndy Shevchenko 	/* Select port... */
1174a039dfb9SAndy Shevchenko 	ret = regmap_write(chip->regmap, CY8C95X0_PORTSEL, port);
1175a039dfb9SAndy Shevchenko 	if (ret)
1176a039dfb9SAndy Shevchenko 		return ret;
1177a039dfb9SAndy Shevchenko 
1178a039dfb9SAndy Shevchenko 	/* ...then direction */
1179a039dfb9SAndy Shevchenko 	ret = regmap_write_bits(chip->regmap, CY8C95X0_DIRECTION, bit, input ? bit : 0);
1180a039dfb9SAndy Shevchenko 	if (ret)
1181a039dfb9SAndy Shevchenko 		return ret;
1182a039dfb9SAndy Shevchenko 
1183a039dfb9SAndy Shevchenko 	/*
1184a039dfb9SAndy Shevchenko 	 * Disable driving the pin by forcing it to HighZ. Only setting
1185a039dfb9SAndy Shevchenko 	 * the direction register isn't sufficient in Push-Pull mode.
1186a039dfb9SAndy Shevchenko 	 */
1187a039dfb9SAndy Shevchenko 	if (input && test_bit(pin, chip->push_pull)) {
1188a039dfb9SAndy Shevchenko 		ret = regmap_write_bits(chip->regmap, CY8C95X0_DRV_HIZ, bit, bit);
1189a039dfb9SAndy Shevchenko 		if (ret)
1190a039dfb9SAndy Shevchenko 			return ret;
1191a039dfb9SAndy Shevchenko 
1192a039dfb9SAndy Shevchenko 		__clear_bit(pin, chip->push_pull);
1193a039dfb9SAndy Shevchenko 	}
1194a039dfb9SAndy Shevchenko 
1195a039dfb9SAndy Shevchenko 	return 0;
1196a039dfb9SAndy Shevchenko }
1197a039dfb9SAndy Shevchenko 
cy8c95x0_gpio_set_direction(struct pinctrl_dev * pctldev,struct pinctrl_gpio_range * range,unsigned int pin,bool input)1198a039dfb9SAndy Shevchenko static int cy8c95x0_gpio_set_direction(struct pinctrl_dev *pctldev,
1199a039dfb9SAndy Shevchenko 				       struct pinctrl_gpio_range *range,
1200a039dfb9SAndy Shevchenko 				       unsigned int pin, bool input)
1201a039dfb9SAndy Shevchenko {
1202a039dfb9SAndy Shevchenko 	struct cy8c95x0_pinctrl *chip = pinctrl_dev_get_drvdata(pctldev);
1203a039dfb9SAndy Shevchenko 	int ret;
1204a039dfb9SAndy Shevchenko 
1205a039dfb9SAndy Shevchenko 	mutex_lock(&chip->i2c_lock);
1206a039dfb9SAndy Shevchenko 	ret = cy8c95x0_pinmux_direction(chip, pin, input);
1207a039dfb9SAndy Shevchenko 	mutex_unlock(&chip->i2c_lock);
1208a039dfb9SAndy Shevchenko 
1209a039dfb9SAndy Shevchenko 	return ret;
1210a039dfb9SAndy Shevchenko }
1211a039dfb9SAndy Shevchenko 
1212e6cbbe42SPatrick Rudolph static const struct pinmux_ops cy8c95x0_pmxops = {
1213e6cbbe42SPatrick Rudolph 	.get_functions_count = cy8c95x0_get_functions_count,
1214ee6cac37SAndy Shevchenko 	.get_function_name = cy8c95x0_get_function_name,
1215ee6cac37SAndy Shevchenko 	.get_function_groups = cy8c95x0_get_function_groups,
1216e6cbbe42SPatrick Rudolph 	.set_mux = cy8c95x0_set_mux,
1217a039dfb9SAndy Shevchenko 	.gpio_request_enable = cy8c95x0_gpio_request_enable,
1218a039dfb9SAndy Shevchenko 	.gpio_set_direction = cy8c95x0_gpio_set_direction,
1219e6cbbe42SPatrick Rudolph 	.strict = true,
1220e6cbbe42SPatrick Rudolph };
1221e6cbbe42SPatrick Rudolph 
cy8c95x0_pinconf_get(struct pinctrl_dev * pctldev,unsigned int pin,unsigned long * config)1222e6cbbe42SPatrick Rudolph static int cy8c95x0_pinconf_get(struct pinctrl_dev *pctldev, unsigned int pin,
1223e6cbbe42SPatrick Rudolph 				unsigned long *config)
1224e6cbbe42SPatrick Rudolph {
1225e6cbbe42SPatrick Rudolph 	struct cy8c95x0_pinctrl *chip = pinctrl_dev_get_drvdata(pctldev);
1226e6cbbe42SPatrick Rudolph 
1227e6cbbe42SPatrick Rudolph 	return cy8c95x0_gpio_get_pincfg(chip, pin, config);
1228e6cbbe42SPatrick Rudolph }
1229e6cbbe42SPatrick Rudolph 
cy8c95x0_pinconf_set(struct pinctrl_dev * pctldev,unsigned int pin,unsigned long * configs,unsigned int num_configs)1230e6cbbe42SPatrick Rudolph static int cy8c95x0_pinconf_set(struct pinctrl_dev *pctldev, unsigned int pin,
1231e6cbbe42SPatrick Rudolph 				unsigned long *configs, unsigned int num_configs)
1232e6cbbe42SPatrick Rudolph {
1233e6cbbe42SPatrick Rudolph 	struct cy8c95x0_pinctrl *chip = pinctrl_dev_get_drvdata(pctldev);
1234e6cbbe42SPatrick Rudolph 	int ret = 0;
1235e6cbbe42SPatrick Rudolph 	int i;
1236e6cbbe42SPatrick Rudolph 
1237e6cbbe42SPatrick Rudolph 	for (i = 0; i < num_configs; i++) {
1238e6cbbe42SPatrick Rudolph 		ret = cy8c95x0_gpio_set_pincfg(chip, pin, configs[i]);
1239e6cbbe42SPatrick Rudolph 		if (ret)
1240e6cbbe42SPatrick Rudolph 			return ret;
1241e6cbbe42SPatrick Rudolph 	}
1242e6cbbe42SPatrick Rudolph 
1243e6cbbe42SPatrick Rudolph 	return ret;
1244e6cbbe42SPatrick Rudolph }
1245e6cbbe42SPatrick Rudolph 
1246e6cbbe42SPatrick Rudolph static const struct pinconf_ops cy8c95x0_pinconf_ops = {
1247e6cbbe42SPatrick Rudolph 	.pin_config_get = cy8c95x0_pinconf_get,
1248e6cbbe42SPatrick Rudolph 	.pin_config_set = cy8c95x0_pinconf_set,
1249e6cbbe42SPatrick Rudolph 	.is_generic = true,
1250e6cbbe42SPatrick Rudolph };
1251e6cbbe42SPatrick Rudolph 
cy8c95x0_irq_setup(struct cy8c95x0_pinctrl * chip,int irq)1252e6cbbe42SPatrick Rudolph static int cy8c95x0_irq_setup(struct cy8c95x0_pinctrl *chip, int irq)
1253e6cbbe42SPatrick Rudolph {
1254e6cbbe42SPatrick Rudolph 	struct gpio_irq_chip *girq = &chip->gpio_chip.irq;
1255e6cbbe42SPatrick Rudolph 	DECLARE_BITMAP(pending_irqs, MAX_LINE);
1256e6cbbe42SPatrick Rudolph 	int ret;
1257e6cbbe42SPatrick Rudolph 
1258e6cbbe42SPatrick Rudolph 	mutex_init(&chip->irq_lock);
1259e6cbbe42SPatrick Rudolph 
1260e6cbbe42SPatrick Rudolph 	bitmap_zero(pending_irqs, MAX_LINE);
1261e6cbbe42SPatrick Rudolph 
1262e6cbbe42SPatrick Rudolph 	/* Read IRQ status register to clear all pending interrupts */
1263e6cbbe42SPatrick Rudolph 	ret = cy8c95x0_irq_pending(chip, pending_irqs);
1264e6cbbe42SPatrick Rudolph 	if (ret) {
1265e6cbbe42SPatrick Rudolph 		dev_err(chip->dev, "failed to clear irq status register\n");
1266e6cbbe42SPatrick Rudolph 		return ret;
1267e6cbbe42SPatrick Rudolph 	}
1268e6cbbe42SPatrick Rudolph 
1269e6cbbe42SPatrick Rudolph 	/* Mask all interrupts */
1270e6cbbe42SPatrick Rudolph 	bitmap_fill(chip->irq_mask, MAX_LINE);
1271e6cbbe42SPatrick Rudolph 
1272f5d62025SAndy Shevchenko 	gpio_irq_chip_set_chip(girq, &cy8c95x0_irqchip);
1273e6cbbe42SPatrick Rudolph 
1274e6cbbe42SPatrick Rudolph 	/* This will let us handle the parent IRQ in the driver */
1275e6cbbe42SPatrick Rudolph 	girq->parent_handler = NULL;
1276e6cbbe42SPatrick Rudolph 	girq->num_parents = 0;
1277e6cbbe42SPatrick Rudolph 	girq->parents = NULL;
1278e6cbbe42SPatrick Rudolph 	girq->default_type = IRQ_TYPE_NONE;
1279e6cbbe42SPatrick Rudolph 	girq->handler = handle_simple_irq;
1280e6cbbe42SPatrick Rudolph 	girq->threaded = true;
1281e6cbbe42SPatrick Rudolph 
1282e6cbbe42SPatrick Rudolph 	ret = devm_request_threaded_irq(chip->dev, irq,
1283e6cbbe42SPatrick Rudolph 					NULL, cy8c95x0_irq_handler,
1284e6cbbe42SPatrick Rudolph 					IRQF_ONESHOT | IRQF_SHARED | IRQF_TRIGGER_HIGH,
1285e6cbbe42SPatrick Rudolph 					dev_name(chip->dev), chip);
1286e6cbbe42SPatrick Rudolph 	if (ret) {
1287e6cbbe42SPatrick Rudolph 		dev_err(chip->dev, "failed to request irq %d\n", irq);
1288e6cbbe42SPatrick Rudolph 		return ret;
1289e6cbbe42SPatrick Rudolph 	}
1290e6cbbe42SPatrick Rudolph 	dev_info(chip->dev, "Registered threaded IRQ\n");
1291e6cbbe42SPatrick Rudolph 
1292e6cbbe42SPatrick Rudolph 	return 0;
1293e6cbbe42SPatrick Rudolph }
1294e6cbbe42SPatrick Rudolph 
cy8c95x0_setup_pinctrl(struct cy8c95x0_pinctrl * chip)1295e6cbbe42SPatrick Rudolph static int cy8c95x0_setup_pinctrl(struct cy8c95x0_pinctrl *chip)
1296e6cbbe42SPatrick Rudolph {
1297e6cbbe42SPatrick Rudolph 	struct pinctrl_desc *pd = &chip->pinctrl_desc;
1298e6cbbe42SPatrick Rudolph 
1299e6cbbe42SPatrick Rudolph 	pd->pctlops = &cy8c95x0_pinctrl_ops;
1300e6cbbe42SPatrick Rudolph 	pd->confops = &cy8c95x0_pinconf_ops;
1301e6cbbe42SPatrick Rudolph 	pd->pmxops = &cy8c95x0_pmxops;
1302641d6cc6SAndy Shevchenko 	pd->name = dev_name(chip->dev);
1303e6cbbe42SPatrick Rudolph 	pd->pins = cy8c9560_pins;
1304e6cbbe42SPatrick Rudolph 	pd->npins = chip->tpin;
1305e6cbbe42SPatrick Rudolph 	pd->owner = THIS_MODULE;
1306e6cbbe42SPatrick Rudolph 
130763e23304SAndy Shevchenko 	chip->pctldev = devm_pinctrl_register(chip->dev, pd, chip);
1308e6cbbe42SPatrick Rudolph 	if (IS_ERR(chip->pctldev))
1309e6cbbe42SPatrick Rudolph 		return dev_err_probe(chip->dev, PTR_ERR(chip->pctldev),
1310e6cbbe42SPatrick Rudolph 			"can't register controller\n");
131163e23304SAndy Shevchenko 
1312e6cbbe42SPatrick Rudolph 	return 0;
1313e6cbbe42SPatrick Rudolph }
1314e6cbbe42SPatrick Rudolph 
cy8c95x0_detect(struct i2c_client * client,struct i2c_board_info * info)1315e6cbbe42SPatrick Rudolph static int cy8c95x0_detect(struct i2c_client *client,
1316e6cbbe42SPatrick Rudolph 			   struct i2c_board_info *info)
1317e6cbbe42SPatrick Rudolph {
1318e6cbbe42SPatrick Rudolph 	struct i2c_adapter *adapter = client->adapter;
1319e6cbbe42SPatrick Rudolph 	int ret;
1320e6cbbe42SPatrick Rudolph 	const char *name;
1321e6cbbe42SPatrick Rudolph 
1322e6cbbe42SPatrick Rudolph 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
1323e6cbbe42SPatrick Rudolph 		return -ENODEV;
1324e6cbbe42SPatrick Rudolph 
1325e6cbbe42SPatrick Rudolph 	ret = i2c_smbus_read_byte_data(client, CY8C95X0_DEVID);
1326e6cbbe42SPatrick Rudolph 	if (ret < 0)
1327e6cbbe42SPatrick Rudolph 		return ret;
13289540a836SAndy Shevchenko 	switch (ret & GENMASK(7, 4)) {
1329e6cbbe42SPatrick Rudolph 	case 0x20:
1330e6cbbe42SPatrick Rudolph 		name = cy8c95x0_id[0].name;
1331e6cbbe42SPatrick Rudolph 		break;
1332e6cbbe42SPatrick Rudolph 	case 0x40:
1333e6cbbe42SPatrick Rudolph 		name = cy8c95x0_id[1].name;
1334e6cbbe42SPatrick Rudolph 		break;
1335e6cbbe42SPatrick Rudolph 	case 0x60:
1336e6cbbe42SPatrick Rudolph 		name = cy8c95x0_id[2].name;
1337e6cbbe42SPatrick Rudolph 		break;
1338e6cbbe42SPatrick Rudolph 	default:
1339e6cbbe42SPatrick Rudolph 		return -ENODEV;
1340e6cbbe42SPatrick Rudolph 	}
1341e6cbbe42SPatrick Rudolph 
1342e6cbbe42SPatrick Rudolph 	dev_info(&client->dev, "Found a %s chip at 0x%02x.\n", name, client->addr);
1343e6cbbe42SPatrick Rudolph 	strscpy(info->type, name, I2C_NAME_SIZE);
1344e6cbbe42SPatrick Rudolph 
134543dcf873SAndy Shevchenko 	return 0;
1346e6cbbe42SPatrick Rudolph }
1347e6cbbe42SPatrick Rudolph 
cy8c95x0_probe(struct i2c_client * client)1348e6cbbe42SPatrick Rudolph static int cy8c95x0_probe(struct i2c_client *client)
1349e6cbbe42SPatrick Rudolph {
1350e6cbbe42SPatrick Rudolph 	struct cy8c95x0_pinctrl *chip;
1351e6cbbe42SPatrick Rudolph 	struct regulator *reg;
1352e6cbbe42SPatrick Rudolph 	int ret;
1353e6cbbe42SPatrick Rudolph 
1354e6cbbe42SPatrick Rudolph 	chip = devm_kzalloc(&client->dev, sizeof(*chip), GFP_KERNEL);
1355e6cbbe42SPatrick Rudolph 	if (!chip)
1356e6cbbe42SPatrick Rudolph 		return -ENOMEM;
1357e6cbbe42SPatrick Rudolph 
1358e6cbbe42SPatrick Rudolph 	chip->dev = &client->dev;
1359e6cbbe42SPatrick Rudolph 
1360e6cbbe42SPatrick Rudolph 	/* Set the device type */
13618586466eSAndy Shevchenko 	chip->driver_data = (unsigned long)device_get_match_data(&client->dev);
13628586466eSAndy Shevchenko 	if (!chip->driver_data)
1363e6cbbe42SPatrick Rudolph 		chip->driver_data = i2c_match_id(cy8c95x0_id, client)->driver_data;
1364e6cbbe42SPatrick Rudolph 	if (!chip->driver_data)
1365e6cbbe42SPatrick Rudolph 		return -ENODEV;
1366e6cbbe42SPatrick Rudolph 
1367e6cbbe42SPatrick Rudolph 	i2c_set_clientdata(client, chip);
1368e6cbbe42SPatrick Rudolph 
1369e6cbbe42SPatrick Rudolph 	chip->tpin = chip->driver_data & CY8C95X0_GPIO_MASK;
1370e6cbbe42SPatrick Rudolph 	chip->nport = DIV_ROUND_UP(CY8C95X0_PIN_TO_OFFSET(chip->tpin), BANK_SZ);
1371e6cbbe42SPatrick Rudolph 
1372e6cbbe42SPatrick Rudolph 	switch (chip->tpin) {
1373e6cbbe42SPatrick Rudolph 	case 20:
1374e6cbbe42SPatrick Rudolph 		strscpy(chip->name, cy8c95x0_id[0].name, I2C_NAME_SIZE);
1375e6cbbe42SPatrick Rudolph 		break;
1376e6cbbe42SPatrick Rudolph 	case 40:
1377e6cbbe42SPatrick Rudolph 		strscpy(chip->name, cy8c95x0_id[1].name, I2C_NAME_SIZE);
1378e6cbbe42SPatrick Rudolph 		break;
1379e6cbbe42SPatrick Rudolph 	case 60:
1380e6cbbe42SPatrick Rudolph 		strscpy(chip->name, cy8c95x0_id[2].name, I2C_NAME_SIZE);
1381e6cbbe42SPatrick Rudolph 		break;
1382c3e40952SAndy Shevchenko 	default:
1383c3e40952SAndy Shevchenko 		return -ENODEV;
1384e6cbbe42SPatrick Rudolph 	}
1385e6cbbe42SPatrick Rudolph 
1386e6cbbe42SPatrick Rudolph 	reg = devm_regulator_get(&client->dev, "vdd");
1387e6cbbe42SPatrick Rudolph 	if (IS_ERR(reg)) {
1388e6cbbe42SPatrick Rudolph 		if (PTR_ERR(reg) == -EPROBE_DEFER)
1389e6cbbe42SPatrick Rudolph 			return -EPROBE_DEFER;
1390e6cbbe42SPatrick Rudolph 	} else {
1391e6cbbe42SPatrick Rudolph 		ret = regulator_enable(reg);
1392e6cbbe42SPatrick Rudolph 		if (ret) {
1393e6cbbe42SPatrick Rudolph 			dev_err(&client->dev, "failed to enable regulator vdd: %d\n", ret);
1394e6cbbe42SPatrick Rudolph 			return ret;
1395e6cbbe42SPatrick Rudolph 		}
1396e6cbbe42SPatrick Rudolph 		chip->regulator = reg;
1397e6cbbe42SPatrick Rudolph 	}
1398e6cbbe42SPatrick Rudolph 
139999084881SPatrick Rudolph 	/* bring the chip out of reset if reset pin is provided */
140099084881SPatrick Rudolph 	chip->gpio_reset = devm_gpiod_get_optional(&client->dev, "reset", GPIOD_OUT_HIGH);
140199084881SPatrick Rudolph 	if (IS_ERR(chip->gpio_reset)) {
140299084881SPatrick Rudolph 		ret = dev_err_probe(chip->dev, PTR_ERR(chip->gpio_reset),
140399084881SPatrick Rudolph 				    "Failed to get GPIO 'reset'\n");
140499084881SPatrick Rudolph 		goto err_exit;
140599084881SPatrick Rudolph 	} else if (chip->gpio_reset) {
140699084881SPatrick Rudolph 		usleep_range(1000, 2000);
140799084881SPatrick Rudolph 		gpiod_set_value_cansleep(chip->gpio_reset, 0);
140899084881SPatrick Rudolph 		usleep_range(250000, 300000);
140999084881SPatrick Rudolph 
141099084881SPatrick Rudolph 		gpiod_set_consumer_name(chip->gpio_reset, "CY8C95X0 RESET");
141199084881SPatrick Rudolph 	}
141299084881SPatrick Rudolph 
1413e6cbbe42SPatrick Rudolph 	chip->regmap = devm_regmap_init_i2c(client, &cy8c95x0_i2c_regmap);
1414e6cbbe42SPatrick Rudolph 	if (IS_ERR(chip->regmap)) {
1415e6cbbe42SPatrick Rudolph 		ret = PTR_ERR(chip->regmap);
1416e6cbbe42SPatrick Rudolph 		goto err_exit;
1417e6cbbe42SPatrick Rudolph 	}
1418e6cbbe42SPatrick Rudolph 
1419e6cbbe42SPatrick Rudolph 	bitmap_zero(chip->push_pull, MAX_LINE);
1420e6cbbe42SPatrick Rudolph 	bitmap_zero(chip->shiftmask, MAX_LINE);
1421e6cbbe42SPatrick Rudolph 	bitmap_set(chip->shiftmask, 0, 20);
1422e6cbbe42SPatrick Rudolph 	mutex_init(&chip->i2c_lock);
1423e6cbbe42SPatrick Rudolph 
1424785b1bd8SAndy Shevchenko 	if (dmi_first_match(cy8c95x0_dmi_acpi_irq_info)) {
1425785b1bd8SAndy Shevchenko 		ret = cy8c95x0_acpi_get_irq(&client->dev);
1426785b1bd8SAndy Shevchenko 		if (ret > 0)
1427785b1bd8SAndy Shevchenko 			client->irq = ret;
1428785b1bd8SAndy Shevchenko 	}
1429785b1bd8SAndy Shevchenko 
1430e6cbbe42SPatrick Rudolph 	if (client->irq) {
1431e6cbbe42SPatrick Rudolph 		ret = cy8c95x0_irq_setup(chip, client->irq);
1432e6cbbe42SPatrick Rudolph 		if (ret)
1433e6cbbe42SPatrick Rudolph 			goto err_exit;
1434e6cbbe42SPatrick Rudolph 	}
1435e6cbbe42SPatrick Rudolph 
1436d86e0344SAndy Shevchenko 	ret = cy8c95x0_setup_pinctrl(chip);
1437e6cbbe42SPatrick Rudolph 	if (ret)
1438e6cbbe42SPatrick Rudolph 		goto err_exit;
1439e6cbbe42SPatrick Rudolph 
1440d86e0344SAndy Shevchenko 	ret = cy8c95x0_setup_gpiochip(chip);
1441e6cbbe42SPatrick Rudolph 	if (ret)
1442e6cbbe42SPatrick Rudolph 		goto err_exit;
1443e6cbbe42SPatrick Rudolph 
1444e6cbbe42SPatrick Rudolph 	return 0;
1445e6cbbe42SPatrick Rudolph 
1446e6cbbe42SPatrick Rudolph err_exit:
1447e6cbbe42SPatrick Rudolph 	if (!IS_ERR_OR_NULL(chip->regulator))
1448e6cbbe42SPatrick Rudolph 		regulator_disable(chip->regulator);
1449e6cbbe42SPatrick Rudolph 	return ret;
1450e6cbbe42SPatrick Rudolph }
1451e6cbbe42SPatrick Rudolph 
cy8c95x0_remove(struct i2c_client * client)1452bbe2a5d8SStephen Rothwell static void cy8c95x0_remove(struct i2c_client *client)
1453e6cbbe42SPatrick Rudolph {
1454e6cbbe42SPatrick Rudolph 	struct cy8c95x0_pinctrl *chip = i2c_get_clientdata(client);
1455e6cbbe42SPatrick Rudolph 
1456e6cbbe42SPatrick Rudolph 	if (!IS_ERR_OR_NULL(chip->regulator))
1457e6cbbe42SPatrick Rudolph 		regulator_disable(chip->regulator);
1458e6cbbe42SPatrick Rudolph }
1459e6cbbe42SPatrick Rudolph 
1460618a43ffSAndy Shevchenko static const struct acpi_device_id cy8c95x0_acpi_ids[] = {
1461618a43ffSAndy Shevchenko 	{ "INT3490", 40, },
1462618a43ffSAndy Shevchenko 	{ }
1463618a43ffSAndy Shevchenko };
1464618a43ffSAndy Shevchenko MODULE_DEVICE_TABLE(acpi, cy8c95x0_acpi_ids);
1465618a43ffSAndy Shevchenko 
1466e6cbbe42SPatrick Rudolph static struct i2c_driver cy8c95x0_driver = {
1467e6cbbe42SPatrick Rudolph 	.driver = {
1468e6cbbe42SPatrick Rudolph 		.name	= "cy8c95x0-pinctrl",
1469e6cbbe42SPatrick Rudolph 		.of_match_table = cy8c95x0_dt_ids,
1470618a43ffSAndy Shevchenko 		.acpi_match_table = cy8c95x0_acpi_ids,
1471e6cbbe42SPatrick Rudolph 	},
1472d8572531SUwe Kleine-König 	.probe		= cy8c95x0_probe,
1473e6cbbe42SPatrick Rudolph 	.remove		= cy8c95x0_remove,
1474e6cbbe42SPatrick Rudolph 	.id_table	= cy8c95x0_id,
1475e6cbbe42SPatrick Rudolph 	.detect		= cy8c95x0_detect,
1476e6cbbe42SPatrick Rudolph };
1477e6cbbe42SPatrick Rudolph module_i2c_driver(cy8c95x0_driver);
1478e6cbbe42SPatrick Rudolph 
1479e6cbbe42SPatrick Rudolph MODULE_AUTHOR("Patrick Rudolph <patrick.rudolph@9elements.com>");
1480e6cbbe42SPatrick Rudolph MODULE_AUTHOR("Naresh Solanki <naresh.solanki@9elements.com>");
1481e6cbbe42SPatrick Rudolph MODULE_DESCRIPTION("Pinctrl driver for CY8C95X0");
1482e6cbbe42SPatrick Rudolph MODULE_LICENSE("GPL");
1483