xref: /openbmc/linux/drivers/hid/hid-mcp2200.c (revision 7b7fd0ac7dc1ffcaf24d9bca0f051b0168e43cd4)
1*b289b834SJohannes Roith // SPDX-License-Identifier: GPL-2.0-only
2*b289b834SJohannes Roith /*
3*b289b834SJohannes Roith  * MCP2200 - Microchip USB to GPIO bridge
4*b289b834SJohannes Roith  *
5*b289b834SJohannes Roith  * Copyright (c) 2023, Johannes Roith <johannes@gnu-linux.rocks>
6*b289b834SJohannes Roith  *
7*b289b834SJohannes Roith  * Datasheet: https://ww1.microchip.com/downloads/en/DeviceDoc/22228A.pdf
8*b289b834SJohannes Roith  * App Note for HID: https://ww1.microchip.com/downloads/en/DeviceDoc/93066A.pdf
9*b289b834SJohannes Roith  */
10*b289b834SJohannes Roith #include <linux/completion.h>
11*b289b834SJohannes Roith #include <linux/delay.h>
12*b289b834SJohannes Roith #include <linux/err.h>
13*b289b834SJohannes Roith #include <linux/gpio/driver.h>
14*b289b834SJohannes Roith #include <linux/hid.h>
15*b289b834SJohannes Roith #include <linux/hidraw.h>
16*b289b834SJohannes Roith #include <linux/module.h>
17*b289b834SJohannes Roith #include <linux/mutex.h>
18*b289b834SJohannes Roith #include "hid-ids.h"
19*b289b834SJohannes Roith 
20*b289b834SJohannes Roith /* Commands codes in a raw output report */
21*b289b834SJohannes Roith #define SET_CLEAR_OUTPUTS	0x08
22*b289b834SJohannes Roith #define CONFIGURE		0x10
23*b289b834SJohannes Roith #define READ_EE			0x20
24*b289b834SJohannes Roith #define WRITE_EE		0x40
25*b289b834SJohannes Roith #define READ_ALL		0x80
26*b289b834SJohannes Roith 
27*b289b834SJohannes Roith /* MCP GPIO direction encoding */
28*b289b834SJohannes Roith enum MCP_IO_DIR {
29*b289b834SJohannes Roith 	MCP2200_DIR_OUT = 0x00,
30*b289b834SJohannes Roith 	MCP2200_DIR_IN  = 0x01,
31*b289b834SJohannes Roith };
32*b289b834SJohannes Roith 
33*b289b834SJohannes Roith /* Altternative pin assignments */
34*b289b834SJohannes Roith #define TXLED		2
35*b289b834SJohannes Roith #define RXLED		3
36*b289b834SJohannes Roith #define USBCFG		6
37*b289b834SJohannes Roith #define SSPND		7
38*b289b834SJohannes Roith #define MCP_NGPIO	8
39*b289b834SJohannes Roith 
40*b289b834SJohannes Roith /* CMD to set or clear a GPIO output */
41*b289b834SJohannes Roith struct mcp_set_clear_outputs {
42*b289b834SJohannes Roith 	u8 cmd;
43*b289b834SJohannes Roith 	u8 dummys1[10];
44*b289b834SJohannes Roith 	u8 set_bmap;
45*b289b834SJohannes Roith 	u8 clear_bmap;
46*b289b834SJohannes Roith 	u8 dummys2[3];
47*b289b834SJohannes Roith } __packed;
48*b289b834SJohannes Roith 
49*b289b834SJohannes Roith /* CMD to configure the IOs */
50*b289b834SJohannes Roith struct mcp_configure {
51*b289b834SJohannes Roith 	u8 cmd;
52*b289b834SJohannes Roith 	u8 dummys1[3];
53*b289b834SJohannes Roith 	u8 io_bmap;
54*b289b834SJohannes Roith 	u8 config_alt_pins;
55*b289b834SJohannes Roith 	u8 io_default_val_bmap;
56*b289b834SJohannes Roith 	u8 config_alt_options;
57*b289b834SJohannes Roith 	u8 baud_h;
58*b289b834SJohannes Roith 	u8 baud_l;
59*b289b834SJohannes Roith 	u8 dummys2[6];
60*b289b834SJohannes Roith } __packed;
61*b289b834SJohannes Roith 
62*b289b834SJohannes Roith /* CMD to read all parameters */
63*b289b834SJohannes Roith struct mcp_read_all {
64*b289b834SJohannes Roith 	u8 cmd;
65*b289b834SJohannes Roith 	u8 dummys[15];
66*b289b834SJohannes Roith } __packed;
67*b289b834SJohannes Roith 
68*b289b834SJohannes Roith /* Response to the read all cmd */
69*b289b834SJohannes Roith struct mcp_read_all_resp {
70*b289b834SJohannes Roith 	u8 cmd;
71*b289b834SJohannes Roith 	u8 eep_addr;
72*b289b834SJohannes Roith 	u8 dummy;
73*b289b834SJohannes Roith 	u8 eep_val;
74*b289b834SJohannes Roith 	u8 io_bmap;
75*b289b834SJohannes Roith 	u8 config_alt_pins;
76*b289b834SJohannes Roith 	u8 io_default_val_bmap;
77*b289b834SJohannes Roith 	u8 config_alt_options;
78*b289b834SJohannes Roith 	u8 baud_h;
79*b289b834SJohannes Roith 	u8 baud_l;
80*b289b834SJohannes Roith 	u8 io_port_val_bmap;
81*b289b834SJohannes Roith 	u8 dummys[5];
82*b289b834SJohannes Roith } __packed;
83*b289b834SJohannes Roith 
84*b289b834SJohannes Roith struct mcp2200 {
85*b289b834SJohannes Roith 	struct hid_device *hdev;
86*b289b834SJohannes Roith 	struct mutex lock;
87*b289b834SJohannes Roith 	struct completion wait_in_report;
88*b289b834SJohannes Roith 	u8 gpio_dir;
89*b289b834SJohannes Roith 	u8 gpio_val;
90*b289b834SJohannes Roith 	u8 gpio_inval;
91*b289b834SJohannes Roith 	u8 baud_h;
92*b289b834SJohannes Roith 	u8 baud_l;
93*b289b834SJohannes Roith 	u8 config_alt_pins;
94*b289b834SJohannes Roith 	u8 gpio_reset_val;
95*b289b834SJohannes Roith 	u8 config_alt_options;
96*b289b834SJohannes Roith 	int status;
97*b289b834SJohannes Roith 	struct gpio_chip gc;
98*b289b834SJohannes Roith 	u8 hid_report[16];
99*b289b834SJohannes Roith };
100*b289b834SJohannes Roith 
101*b289b834SJohannes Roith /* this executes the READ_ALL cmd */
mcp_cmd_read_all(struct mcp2200 * mcp)102*b289b834SJohannes Roith static int mcp_cmd_read_all(struct mcp2200 *mcp)
103*b289b834SJohannes Roith {
104*b289b834SJohannes Roith 	struct mcp_read_all *read_all;
105*b289b834SJohannes Roith 	int len, t;
106*b289b834SJohannes Roith 
107*b289b834SJohannes Roith 	reinit_completion(&mcp->wait_in_report);
108*b289b834SJohannes Roith 
109*b289b834SJohannes Roith 	mutex_lock(&mcp->lock);
110*b289b834SJohannes Roith 
111*b289b834SJohannes Roith 	read_all = (struct mcp_read_all *) mcp->hid_report;
112*b289b834SJohannes Roith 	read_all->cmd = READ_ALL;
113*b289b834SJohannes Roith 	len = hid_hw_output_report(mcp->hdev, (u8 *) read_all,
114*b289b834SJohannes Roith 				   sizeof(struct mcp_read_all));
115*b289b834SJohannes Roith 
116*b289b834SJohannes Roith 	mutex_unlock(&mcp->lock);
117*b289b834SJohannes Roith 
118*b289b834SJohannes Roith 	if (len != sizeof(struct mcp_read_all))
119*b289b834SJohannes Roith 		return -EINVAL;
120*b289b834SJohannes Roith 
121*b289b834SJohannes Roith 	t = wait_for_completion_timeout(&mcp->wait_in_report,
122*b289b834SJohannes Roith 					msecs_to_jiffies(4000));
123*b289b834SJohannes Roith 	if (!t)
124*b289b834SJohannes Roith 		return -ETIMEDOUT;
125*b289b834SJohannes Roith 
126*b289b834SJohannes Roith 	/* return status, negative value if wrong response was received */
127*b289b834SJohannes Roith 	return mcp->status;
128*b289b834SJohannes Roith }
129*b289b834SJohannes Roith 
mcp_set_multiple(struct gpio_chip * gc,unsigned long * mask,unsigned long * bits)130*b289b834SJohannes Roith static void mcp_set_multiple(struct gpio_chip *gc, unsigned long *mask,
131*b289b834SJohannes Roith 			     unsigned long *bits)
132*b289b834SJohannes Roith {
133*b289b834SJohannes Roith 	struct mcp2200 *mcp = gpiochip_get_data(gc);
134*b289b834SJohannes Roith 	u8 value;
135*b289b834SJohannes Roith 	int status;
136*b289b834SJohannes Roith 	struct mcp_set_clear_outputs *cmd;
137*b289b834SJohannes Roith 
138*b289b834SJohannes Roith 	mutex_lock(&mcp->lock);
139*b289b834SJohannes Roith 	cmd = (struct mcp_set_clear_outputs *) mcp->hid_report;
140*b289b834SJohannes Roith 
141*b289b834SJohannes Roith 	value = mcp->gpio_val & ~*mask;
142*b289b834SJohannes Roith 	value |= (*mask & *bits);
143*b289b834SJohannes Roith 
144*b289b834SJohannes Roith 	cmd->cmd = SET_CLEAR_OUTPUTS;
145*b289b834SJohannes Roith 	cmd->set_bmap = value;
146*b289b834SJohannes Roith 	cmd->clear_bmap = ~(value);
147*b289b834SJohannes Roith 
148*b289b834SJohannes Roith 	status = hid_hw_output_report(mcp->hdev, (u8 *) cmd,
149*b289b834SJohannes Roith 		       sizeof(struct mcp_set_clear_outputs));
150*b289b834SJohannes Roith 
151*b289b834SJohannes Roith 	if (status == sizeof(struct mcp_set_clear_outputs))
152*b289b834SJohannes Roith 		mcp->gpio_val = value;
153*b289b834SJohannes Roith 
154*b289b834SJohannes Roith 	mutex_unlock(&mcp->lock);
155*b289b834SJohannes Roith }
156*b289b834SJohannes Roith 
mcp_set(struct gpio_chip * gc,unsigned int gpio_nr,int value)157*b289b834SJohannes Roith static void mcp_set(struct gpio_chip *gc, unsigned int gpio_nr, int value)
158*b289b834SJohannes Roith {
159*b289b834SJohannes Roith 	unsigned long mask = 1 << gpio_nr;
160*b289b834SJohannes Roith 	unsigned long bmap_value = value << gpio_nr;
161*b289b834SJohannes Roith 
162*b289b834SJohannes Roith 	mcp_set_multiple(gc, &mask, &bmap_value);
163*b289b834SJohannes Roith }
164*b289b834SJohannes Roith 
mcp_get_multiple(struct gpio_chip * gc,unsigned long * mask,unsigned long * bits)165*b289b834SJohannes Roith static int mcp_get_multiple(struct gpio_chip *gc, unsigned long *mask,
166*b289b834SJohannes Roith 		unsigned long *bits)
167*b289b834SJohannes Roith {
168*b289b834SJohannes Roith 	u32 val;
169*b289b834SJohannes Roith 	struct mcp2200 *mcp = gpiochip_get_data(gc);
170*b289b834SJohannes Roith 	int status;
171*b289b834SJohannes Roith 
172*b289b834SJohannes Roith 	status = mcp_cmd_read_all(mcp);
173*b289b834SJohannes Roith 	if (status)
174*b289b834SJohannes Roith 		return status;
175*b289b834SJohannes Roith 
176*b289b834SJohannes Roith 	val = mcp->gpio_inval;
177*b289b834SJohannes Roith 	*bits = (val & *mask);
178*b289b834SJohannes Roith 	return 0;
179*b289b834SJohannes Roith }
180*b289b834SJohannes Roith 
mcp_get(struct gpio_chip * gc,unsigned int gpio_nr)181*b289b834SJohannes Roith static int mcp_get(struct gpio_chip *gc, unsigned int gpio_nr)
182*b289b834SJohannes Roith {
183*b289b834SJohannes Roith 	unsigned long mask = 0, bits = 0;
184*b289b834SJohannes Roith 
185*b289b834SJohannes Roith 	mask = (1 << gpio_nr);
186*b289b834SJohannes Roith 	mcp_get_multiple(gc, &mask, &bits);
187*b289b834SJohannes Roith 	return bits > 0;
188*b289b834SJohannes Roith }
189*b289b834SJohannes Roith 
mcp_get_direction(struct gpio_chip * gc,unsigned int gpio_nr)190*b289b834SJohannes Roith static int mcp_get_direction(struct gpio_chip *gc, unsigned int gpio_nr)
191*b289b834SJohannes Roith {
192*b289b834SJohannes Roith 	struct mcp2200 *mcp = gpiochip_get_data(gc);
193*b289b834SJohannes Roith 
194*b289b834SJohannes Roith 	return (mcp->gpio_dir & (MCP2200_DIR_IN << gpio_nr))
195*b289b834SJohannes Roith 		? GPIO_LINE_DIRECTION_IN : GPIO_LINE_DIRECTION_OUT;
196*b289b834SJohannes Roith }
197*b289b834SJohannes Roith 
mcp_set_direction(struct gpio_chip * gc,unsigned int gpio_nr,enum MCP_IO_DIR io_direction)198*b289b834SJohannes Roith static int mcp_set_direction(struct gpio_chip *gc, unsigned int gpio_nr,
199*b289b834SJohannes Roith 			     enum MCP_IO_DIR io_direction)
200*b289b834SJohannes Roith {
201*b289b834SJohannes Roith 	struct mcp2200 *mcp = gpiochip_get_data(gc);
202*b289b834SJohannes Roith 	struct mcp_configure *conf;
203*b289b834SJohannes Roith 	int status;
204*b289b834SJohannes Roith 	/* after the configure cmd we will need to set the outputs again */
205*b289b834SJohannes Roith 	unsigned long mask = ~(mcp->gpio_dir); /* only set outputs */
206*b289b834SJohannes Roith 	unsigned long bits = mcp->gpio_val;
207*b289b834SJohannes Roith 	/* Offsets of alternative pins in config_alt_pins, 0 is not used */
208*b289b834SJohannes Roith 	u8 alt_pin_conf[8] = {SSPND, USBCFG, 0, 0, 0, 0, RXLED, TXLED};
209*b289b834SJohannes Roith 	u8 config_alt_pins = mcp->config_alt_pins;
210*b289b834SJohannes Roith 
211*b289b834SJohannes Roith 	/* Read in the reset baudrate first, we need it later */
212*b289b834SJohannes Roith 	status = mcp_cmd_read_all(mcp);
213*b289b834SJohannes Roith 	if (status != 0)
214*b289b834SJohannes Roith 		return status;
215*b289b834SJohannes Roith 
216*b289b834SJohannes Roith 	mutex_lock(&mcp->lock);
217*b289b834SJohannes Roith 	conf = (struct mcp_configure  *) mcp->hid_report;
218*b289b834SJohannes Roith 
219*b289b834SJohannes Roith 	/* configure will reset the chip! */
220*b289b834SJohannes Roith 	conf->cmd = CONFIGURE;
221*b289b834SJohannes Roith 	conf->io_bmap = (mcp->gpio_dir & ~(1 << gpio_nr))
222*b289b834SJohannes Roith 		| (io_direction << gpio_nr);
223*b289b834SJohannes Roith 	/* Don't overwrite the reset parameters */
224*b289b834SJohannes Roith 	conf->baud_h = mcp->baud_h;
225*b289b834SJohannes Roith 	conf->baud_l = mcp->baud_l;
226*b289b834SJohannes Roith 	conf->config_alt_options = mcp->config_alt_options;
227*b289b834SJohannes Roith 	conf->io_default_val_bmap = mcp->gpio_reset_val;
228*b289b834SJohannes Roith 	/* Adjust alt. func if necessary */
229*b289b834SJohannes Roith 	if (alt_pin_conf[gpio_nr])
230*b289b834SJohannes Roith 		config_alt_pins &= ~(1 << alt_pin_conf[gpio_nr]);
231*b289b834SJohannes Roith 	conf->config_alt_pins = config_alt_pins;
232*b289b834SJohannes Roith 
233*b289b834SJohannes Roith 	status = hid_hw_output_report(mcp->hdev, (u8 *) conf,
234*b289b834SJohannes Roith 				      sizeof(struct mcp_set_clear_outputs));
235*b289b834SJohannes Roith 
236*b289b834SJohannes Roith 	if (status == sizeof(struct mcp_set_clear_outputs)) {
237*b289b834SJohannes Roith 		mcp->gpio_dir = conf->io_bmap;
238*b289b834SJohannes Roith 		mcp->config_alt_pins = config_alt_pins;
239*b289b834SJohannes Roith 	} else {
240*b289b834SJohannes Roith 		mutex_unlock(&mcp->lock);
241*b289b834SJohannes Roith 		return -EIO;
242*b289b834SJohannes Roith 	}
243*b289b834SJohannes Roith 
244*b289b834SJohannes Roith 	mutex_unlock(&mcp->lock);
245*b289b834SJohannes Roith 
246*b289b834SJohannes Roith 	/* Configure CMD will clear all IOs -> rewrite them */
247*b289b834SJohannes Roith 	mcp_set_multiple(gc, &mask, &bits);
248*b289b834SJohannes Roith 	return 0;
249*b289b834SJohannes Roith }
250*b289b834SJohannes Roith 
mcp_direction_input(struct gpio_chip * gc,unsigned int gpio_nr)251*b289b834SJohannes Roith static int mcp_direction_input(struct gpio_chip *gc, unsigned int gpio_nr)
252*b289b834SJohannes Roith {
253*b289b834SJohannes Roith 	return mcp_set_direction(gc, gpio_nr, MCP2200_DIR_IN);
254*b289b834SJohannes Roith }
255*b289b834SJohannes Roith 
mcp_direction_output(struct gpio_chip * gc,unsigned int gpio_nr,int value)256*b289b834SJohannes Roith static int mcp_direction_output(struct gpio_chip *gc, unsigned int gpio_nr,
257*b289b834SJohannes Roith 				int value)
258*b289b834SJohannes Roith {
259*b289b834SJohannes Roith 	int ret;
260*b289b834SJohannes Roith 	unsigned long mask, bmap_value;
261*b289b834SJohannes Roith 
262*b289b834SJohannes Roith 	mask = 1 << gpio_nr;
263*b289b834SJohannes Roith 	bmap_value = value << gpio_nr;
264*b289b834SJohannes Roith 
265*b289b834SJohannes Roith 	ret = mcp_set_direction(gc, gpio_nr, MCP2200_DIR_OUT);
266*b289b834SJohannes Roith 	if (!ret)
267*b289b834SJohannes Roith 		mcp_set_multiple(gc, &mask, &bmap_value);
268*b289b834SJohannes Roith 	return ret;
269*b289b834SJohannes Roith }
270*b289b834SJohannes Roith 
271*b289b834SJohannes Roith static const struct gpio_chip template_chip = {
272*b289b834SJohannes Roith 	.label			= "mcp2200",
273*b289b834SJohannes Roith 	.owner			= THIS_MODULE,
274*b289b834SJohannes Roith 	.get_direction		= mcp_get_direction,
275*b289b834SJohannes Roith 	.direction_input	= mcp_direction_input,
276*b289b834SJohannes Roith 	.direction_output	= mcp_direction_output,
277*b289b834SJohannes Roith 	.set			= mcp_set,
278*b289b834SJohannes Roith 	.set_multiple		= mcp_set_multiple,
279*b289b834SJohannes Roith 	.get			= mcp_get,
280*b289b834SJohannes Roith 	.get_multiple		= mcp_get_multiple,
281*b289b834SJohannes Roith 	.base			= -1,
282*b289b834SJohannes Roith 	.ngpio			= MCP_NGPIO,
283*b289b834SJohannes Roith 	.can_sleep		= true,
284*b289b834SJohannes Roith };
285*b289b834SJohannes Roith 
286*b289b834SJohannes Roith /*
287*b289b834SJohannes Roith  * MCP2200 uses interrupt endpoint for input reports. This function
288*b289b834SJohannes Roith  * is called by HID layer when it receives i/p report from mcp2200,
289*b289b834SJohannes Roith  * which is actually a response to the previously sent command.
290*b289b834SJohannes Roith  */
mcp2200_raw_event(struct hid_device * hdev,struct hid_report * report,u8 * data,int size)291*b289b834SJohannes Roith static int mcp2200_raw_event(struct hid_device *hdev, struct hid_report *report,
292*b289b834SJohannes Roith 		u8 *data, int size)
293*b289b834SJohannes Roith {
294*b289b834SJohannes Roith 	struct mcp2200 *mcp = hid_get_drvdata(hdev);
295*b289b834SJohannes Roith 	struct mcp_read_all_resp *all_resp;
296*b289b834SJohannes Roith 
297*b289b834SJohannes Roith 	switch (data[0]) {
298*b289b834SJohannes Roith 	case READ_ALL:
299*b289b834SJohannes Roith 		all_resp = (struct mcp_read_all_resp *) data;
300*b289b834SJohannes Roith 		mcp->status = 0;
301*b289b834SJohannes Roith 		mcp->gpio_inval = all_resp->io_port_val_bmap;
302*b289b834SJohannes Roith 		mcp->baud_h = all_resp->baud_h;
303*b289b834SJohannes Roith 		mcp->baud_l = all_resp->baud_l;
304*b289b834SJohannes Roith 		mcp->gpio_reset_val = all_resp->io_default_val_bmap;
305*b289b834SJohannes Roith 		mcp->config_alt_pins = all_resp->config_alt_pins;
306*b289b834SJohannes Roith 		mcp->config_alt_options = all_resp->config_alt_options;
307*b289b834SJohannes Roith 		break;
308*b289b834SJohannes Roith 	default:
309*b289b834SJohannes Roith 		mcp->status = -EIO;
310*b289b834SJohannes Roith 		break;
311*b289b834SJohannes Roith 	}
312*b289b834SJohannes Roith 
313*b289b834SJohannes Roith 	complete(&mcp->wait_in_report);
314*b289b834SJohannes Roith 	return 0;
315*b289b834SJohannes Roith }
316*b289b834SJohannes Roith 
mcp2200_probe(struct hid_device * hdev,const struct hid_device_id * id)317*b289b834SJohannes Roith static int mcp2200_probe(struct hid_device *hdev, const struct hid_device_id *id)
318*b289b834SJohannes Roith {
319*b289b834SJohannes Roith 	int ret;
320*b289b834SJohannes Roith 	struct mcp2200 *mcp;
321*b289b834SJohannes Roith 
322*b289b834SJohannes Roith 	mcp = devm_kzalloc(&hdev->dev, sizeof(*mcp), GFP_KERNEL);
323*b289b834SJohannes Roith 	if (!mcp)
324*b289b834SJohannes Roith 		return -ENOMEM;
325*b289b834SJohannes Roith 
326*b289b834SJohannes Roith 	ret = hid_parse(hdev);
327*b289b834SJohannes Roith 	if (ret) {
328*b289b834SJohannes Roith 		hid_err(hdev, "can't parse reports\n");
329*b289b834SJohannes Roith 		return ret;
330*b289b834SJohannes Roith 	}
331*b289b834SJohannes Roith 
332*b289b834SJohannes Roith 	ret = hid_hw_start(hdev, 0);
333*b289b834SJohannes Roith 	if (ret) {
334*b289b834SJohannes Roith 		hid_err(hdev, "can't start hardware\n");
335*b289b834SJohannes Roith 		return ret;
336*b289b834SJohannes Roith 	}
337*b289b834SJohannes Roith 
338*b289b834SJohannes Roith 	hid_info(hdev, "USB HID v%x.%02x Device [%s] on %s\n", hdev->version >> 8,
339*b289b834SJohannes Roith 			hdev->version & 0xff, hdev->name, hdev->phys);
340*b289b834SJohannes Roith 
341*b289b834SJohannes Roith 	ret = hid_hw_open(hdev);
342*b289b834SJohannes Roith 	if (ret) {
343*b289b834SJohannes Roith 		hid_err(hdev, "can't open device\n");
344*b289b834SJohannes Roith 		hid_hw_stop(hdev);
345*b289b834SJohannes Roith 		return ret;
346*b289b834SJohannes Roith 	}
347*b289b834SJohannes Roith 
348*b289b834SJohannes Roith 	mutex_init(&mcp->lock);
349*b289b834SJohannes Roith 	init_completion(&mcp->wait_in_report);
350*b289b834SJohannes Roith 	hid_set_drvdata(hdev, mcp);
351*b289b834SJohannes Roith 	mcp->hdev = hdev;
352*b289b834SJohannes Roith 
353*b289b834SJohannes Roith 	mcp->gc = template_chip;
354*b289b834SJohannes Roith 	mcp->gc.parent = &hdev->dev;
355*b289b834SJohannes Roith 
356*b289b834SJohannes Roith 	ret = devm_gpiochip_add_data(&hdev->dev, &mcp->gc, mcp);
357*b289b834SJohannes Roith 	if (ret < 0) {
358*b289b834SJohannes Roith 		hid_err(hdev, "Unable to register gpiochip\n");
359*b289b834SJohannes Roith 		hid_hw_close(hdev);
360*b289b834SJohannes Roith 		hid_hw_stop(hdev);
361*b289b834SJohannes Roith 		return ret;
362*b289b834SJohannes Roith 	}
363*b289b834SJohannes Roith 
364*b289b834SJohannes Roith 	return 0;
365*b289b834SJohannes Roith }
366*b289b834SJohannes Roith 
mcp2200_remove(struct hid_device * hdev)367*b289b834SJohannes Roith static void mcp2200_remove(struct hid_device *hdev)
368*b289b834SJohannes Roith {
369*b289b834SJohannes Roith 	hid_hw_close(hdev);
370*b289b834SJohannes Roith 	hid_hw_stop(hdev);
371*b289b834SJohannes Roith }
372*b289b834SJohannes Roith 
373*b289b834SJohannes Roith static const struct hid_device_id mcp2200_devices[] = {
374*b289b834SJohannes Roith 	{ HID_USB_DEVICE(USB_VENDOR_ID_MICROCHIP, USB_DEVICE_ID_MCP2200) },
375*b289b834SJohannes Roith 	{ }
376*b289b834SJohannes Roith };
377*b289b834SJohannes Roith MODULE_DEVICE_TABLE(hid, mcp2200_devices);
378*b289b834SJohannes Roith 
379*b289b834SJohannes Roith static struct hid_driver mcp2200_driver = {
380*b289b834SJohannes Roith 	.name		= "mcp2200",
381*b289b834SJohannes Roith 	.id_table	= mcp2200_devices,
382*b289b834SJohannes Roith 	.probe		= mcp2200_probe,
383*b289b834SJohannes Roith 	.remove		= mcp2200_remove,
384*b289b834SJohannes Roith 	.raw_event	= mcp2200_raw_event,
385*b289b834SJohannes Roith };
386*b289b834SJohannes Roith 
387*b289b834SJohannes Roith /* Register with HID core */
388*b289b834SJohannes Roith module_hid_driver(mcp2200_driver);
389*b289b834SJohannes Roith 
390*b289b834SJohannes Roith MODULE_AUTHOR("Johannes Roith <johannes@gnu-linux.rocks>");
391*b289b834SJohannes Roith MODULE_DESCRIPTION("MCP2200 Microchip HID USB to GPIO bridge");
392*b289b834SJohannes Roith MODULE_LICENSE("GPL");
393