xref: /linux/drivers/input/misc/drv2667.c (revision 1c24622572d6ab2ec8e731588d1c131563a64b53)
1*1c246225SDan Murphy /*
2*1c246225SDan Murphy  * DRV2667 haptics driver family
3*1c246225SDan Murphy  *
4*1c246225SDan Murphy  * Author: Dan Murphy <dmurphy@ti.com>
5*1c246225SDan Murphy  *
6*1c246225SDan Murphy  * Copyright: (C) 2014 Texas Instruments, Inc.
7*1c246225SDan Murphy  *
8*1c246225SDan Murphy  * This program is free software; you can redistribute it and/or modify
9*1c246225SDan Murphy  * it under the terms of the GNU General Public License version 2 as
10*1c246225SDan Murphy  * published by the Free Software Foundation.
11*1c246225SDan Murphy  *
12*1c246225SDan Murphy  * This program is distributed in the hope that it will be useful, but
13*1c246225SDan Murphy  * WITHOUT ANY WARRANTY; without even the implied warranty of
14*1c246225SDan Murphy  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15*1c246225SDan Murphy  * General Public License for more details.
16*1c246225SDan Murphy  */
17*1c246225SDan Murphy 
18*1c246225SDan Murphy #include <linux/i2c.h>
19*1c246225SDan Murphy #include <linux/input.h>
20*1c246225SDan Murphy #include <linux/module.h>
21*1c246225SDan Murphy #include <linux/platform_device.h>
22*1c246225SDan Murphy #include <linux/regmap.h>
23*1c246225SDan Murphy #include <linux/slab.h>
24*1c246225SDan Murphy #include <linux/delay.h>
25*1c246225SDan Murphy #include <linux/regulator/consumer.h>
26*1c246225SDan Murphy 
27*1c246225SDan Murphy /* Contol registers */
28*1c246225SDan Murphy #define DRV2667_STATUS	0x00
29*1c246225SDan Murphy #define DRV2667_CTRL_1	0x01
30*1c246225SDan Murphy #define DRV2667_CTRL_2	0x02
31*1c246225SDan Murphy /* Waveform sequencer */
32*1c246225SDan Murphy #define DRV2667_WV_SEQ_0	0x03
33*1c246225SDan Murphy #define DRV2667_WV_SEQ_1	0x04
34*1c246225SDan Murphy #define DRV2667_WV_SEQ_2	0x05
35*1c246225SDan Murphy #define DRV2667_WV_SEQ_3	0x06
36*1c246225SDan Murphy #define DRV2667_WV_SEQ_4	0x07
37*1c246225SDan Murphy #define DRV2667_WV_SEQ_5	0x08
38*1c246225SDan Murphy #define DRV2667_WV_SEQ_6	0x09
39*1c246225SDan Murphy #define DRV2667_WV_SEQ_7	0x0A
40*1c246225SDan Murphy #define DRV2667_FIFO		0x0B
41*1c246225SDan Murphy #define DRV2667_PAGE		0xFF
42*1c246225SDan Murphy #define DRV2667_MAX_REG		DRV2667_PAGE
43*1c246225SDan Murphy 
44*1c246225SDan Murphy #define DRV2667_PAGE_0		0x00
45*1c246225SDan Murphy #define DRV2667_PAGE_1		0x01
46*1c246225SDan Murphy #define DRV2667_PAGE_2		0x02
47*1c246225SDan Murphy #define DRV2667_PAGE_3		0x03
48*1c246225SDan Murphy #define DRV2667_PAGE_4		0x04
49*1c246225SDan Murphy #define DRV2667_PAGE_5		0x05
50*1c246225SDan Murphy #define DRV2667_PAGE_6		0x06
51*1c246225SDan Murphy #define DRV2667_PAGE_7		0x07
52*1c246225SDan Murphy #define DRV2667_PAGE_8		0x08
53*1c246225SDan Murphy 
54*1c246225SDan Murphy /* RAM fields */
55*1c246225SDan Murphy #define DRV2667_RAM_HDR_SZ	0x0
56*1c246225SDan Murphy /* RAM Header addresses */
57*1c246225SDan Murphy #define DRV2667_RAM_START_HI	0x01
58*1c246225SDan Murphy #define DRV2667_RAM_START_LO	0x02
59*1c246225SDan Murphy #define DRV2667_RAM_STOP_HI		0x03
60*1c246225SDan Murphy #define DRV2667_RAM_STOP_LO		0x04
61*1c246225SDan Murphy #define DRV2667_RAM_REPEAT_CT	0x05
62*1c246225SDan Murphy /* RAM data addresses */
63*1c246225SDan Murphy #define DRV2667_RAM_AMP		0x06
64*1c246225SDan Murphy #define DRV2667_RAM_FREQ	0x07
65*1c246225SDan Murphy #define DRV2667_RAM_DURATION	0x08
66*1c246225SDan Murphy #define DRV2667_RAM_ENVELOPE	0x09
67*1c246225SDan Murphy 
68*1c246225SDan Murphy /* Control 1 Register */
69*1c246225SDan Murphy #define DRV2667_25_VPP_GAIN		0x00
70*1c246225SDan Murphy #define DRV2667_50_VPP_GAIN		0x01
71*1c246225SDan Murphy #define DRV2667_75_VPP_GAIN		0x02
72*1c246225SDan Murphy #define DRV2667_100_VPP_GAIN	0x03
73*1c246225SDan Murphy #define DRV2667_DIGITAL_IN		0xfc
74*1c246225SDan Murphy #define DRV2667_ANALOG_IN		(1 << 2)
75*1c246225SDan Murphy 
76*1c246225SDan Murphy /* Control 2 Register */
77*1c246225SDan Murphy #define DRV2667_GO			(1 << 0)
78*1c246225SDan Murphy #define DRV2667_STANDBY		(1 << 6)
79*1c246225SDan Murphy #define DRV2667_DEV_RST		(1 << 7)
80*1c246225SDan Murphy 
81*1c246225SDan Murphy /* RAM Envelope settings */
82*1c246225SDan Murphy #define DRV2667_NO_ENV			0x00
83*1c246225SDan Murphy #define DRV2667_32_MS_ENV		0x01
84*1c246225SDan Murphy #define DRV2667_64_MS_ENV		0x02
85*1c246225SDan Murphy #define DRV2667_96_MS_ENV		0x03
86*1c246225SDan Murphy #define DRV2667_128_MS_ENV		0x04
87*1c246225SDan Murphy #define DRV2667_160_MS_ENV		0x05
88*1c246225SDan Murphy #define DRV2667_192_MS_ENV		0x06
89*1c246225SDan Murphy #define DRV2667_224_MS_ENV		0x07
90*1c246225SDan Murphy #define DRV2667_256_MS_ENV		0x08
91*1c246225SDan Murphy #define DRV2667_512_MS_ENV		0x09
92*1c246225SDan Murphy #define DRV2667_768_MS_ENV		0x0a
93*1c246225SDan Murphy #define DRV2667_1024_MS_ENV		0x0b
94*1c246225SDan Murphy #define DRV2667_1280_MS_ENV		0x0c
95*1c246225SDan Murphy #define DRV2667_1536_MS_ENV		0x0d
96*1c246225SDan Murphy #define DRV2667_1792_MS_ENV		0x0e
97*1c246225SDan Murphy #define DRV2667_2048_MS_ENV		0x0f
98*1c246225SDan Murphy 
99*1c246225SDan Murphy /**
100*1c246225SDan Murphy  * struct drv2667_data -
101*1c246225SDan Murphy  * @input_dev - Pointer to the input device
102*1c246225SDan Murphy  * @client - Pointer to the I2C client
103*1c246225SDan Murphy  * @regmap - Register map of the device
104*1c246225SDan Murphy  * @work - Work item used to off load the enable/disable of the vibration
105*1c246225SDan Murphy  * @regulator - Pointer to the regulator for the IC
106*1c246225SDan Murphy  * @magnitude - Magnitude of the vibration event
107*1c246225SDan Murphy **/
108*1c246225SDan Murphy struct drv2667_data {
109*1c246225SDan Murphy 	struct input_dev *input_dev;
110*1c246225SDan Murphy 	struct i2c_client *client;
111*1c246225SDan Murphy 	struct regmap *regmap;
112*1c246225SDan Murphy 	struct work_struct work;
113*1c246225SDan Murphy 	struct regulator *regulator;
114*1c246225SDan Murphy 	u32 page;
115*1c246225SDan Murphy 	u32 magnitude;
116*1c246225SDan Murphy 	u32 frequency;
117*1c246225SDan Murphy };
118*1c246225SDan Murphy 
119*1c246225SDan Murphy static struct reg_default drv2667_reg_defs[] = {
120*1c246225SDan Murphy 	{ DRV2667_STATUS, 0x02 },
121*1c246225SDan Murphy 	{ DRV2667_CTRL_1, 0x28 },
122*1c246225SDan Murphy 	{ DRV2667_CTRL_2, 0x40 },
123*1c246225SDan Murphy 	{ DRV2667_WV_SEQ_0, 0x00 },
124*1c246225SDan Murphy 	{ DRV2667_WV_SEQ_1, 0x00 },
125*1c246225SDan Murphy 	{ DRV2667_WV_SEQ_2, 0x00 },
126*1c246225SDan Murphy 	{ DRV2667_WV_SEQ_3, 0x00 },
127*1c246225SDan Murphy 	{ DRV2667_WV_SEQ_4, 0x00 },
128*1c246225SDan Murphy 	{ DRV2667_WV_SEQ_5, 0x00 },
129*1c246225SDan Murphy 	{ DRV2667_WV_SEQ_6, 0x00 },
130*1c246225SDan Murphy 	{ DRV2667_WV_SEQ_7, 0x00 },
131*1c246225SDan Murphy 	{ DRV2667_FIFO, 0x00 },
132*1c246225SDan Murphy 	{ DRV2667_PAGE, 0x00 },
133*1c246225SDan Murphy };
134*1c246225SDan Murphy 
135*1c246225SDan Murphy static int drv2667_set_waveform_freq(struct drv2667_data *haptics)
136*1c246225SDan Murphy {
137*1c246225SDan Murphy 	unsigned int read_buf;
138*1c246225SDan Murphy 	int freq;
139*1c246225SDan Murphy 	int error;
140*1c246225SDan Murphy 
141*1c246225SDan Murphy 	/* Per the data sheet:
142*1c246225SDan Murphy 	 * Sinusoid Frequency (Hz) = 7.8125 x Frequency
143*1c246225SDan Murphy 	 */
144*1c246225SDan Murphy 	freq = (haptics->frequency * 1000) / 78125;
145*1c246225SDan Murphy 	if (freq <= 0) {
146*1c246225SDan Murphy 		dev_err(&haptics->client->dev,
147*1c246225SDan Murphy 			"ERROR: Frequency calculated to %i\n", freq);
148*1c246225SDan Murphy 		return -EINVAL;
149*1c246225SDan Murphy 	}
150*1c246225SDan Murphy 
151*1c246225SDan Murphy 	error = regmap_read(haptics->regmap, DRV2667_PAGE, &read_buf);
152*1c246225SDan Murphy 	if (error) {
153*1c246225SDan Murphy 		dev_err(&haptics->client->dev,
154*1c246225SDan Murphy 			"Failed to read the page number: %d\n", error);
155*1c246225SDan Murphy 		return -EIO;
156*1c246225SDan Murphy 	}
157*1c246225SDan Murphy 
158*1c246225SDan Murphy 	if (read_buf == DRV2667_PAGE_0 ||
159*1c246225SDan Murphy 		haptics->page != read_buf) {
160*1c246225SDan Murphy 		error = regmap_write(haptics->regmap,
161*1c246225SDan Murphy 				DRV2667_PAGE, haptics->page);
162*1c246225SDan Murphy 		if (error) {
163*1c246225SDan Murphy 			dev_err(&haptics->client->dev,
164*1c246225SDan Murphy 				"Failed to set the page: %d\n", error);
165*1c246225SDan Murphy 			return -EIO;
166*1c246225SDan Murphy 		}
167*1c246225SDan Murphy 	}
168*1c246225SDan Murphy 
169*1c246225SDan Murphy 	error = regmap_write(haptics->regmap, DRV2667_RAM_FREQ,	freq);
170*1c246225SDan Murphy 	if (error)
171*1c246225SDan Murphy 		dev_err(&haptics->client->dev,
172*1c246225SDan Murphy 				"Failed to set the frequency: %d\n", error);
173*1c246225SDan Murphy 
174*1c246225SDan Murphy 	/* Reset back to original page */
175*1c246225SDan Murphy 	if (read_buf == DRV2667_PAGE_0 ||
176*1c246225SDan Murphy 		haptics->page != read_buf) {
177*1c246225SDan Murphy 		error = regmap_write(haptics->regmap, DRV2667_PAGE, read_buf);
178*1c246225SDan Murphy 		if (error) {
179*1c246225SDan Murphy 			dev_err(&haptics->client->dev,
180*1c246225SDan Murphy 					"Failed to set the page: %d\n", error);
181*1c246225SDan Murphy 				return -EIO;
182*1c246225SDan Murphy 			}
183*1c246225SDan Murphy 	}
184*1c246225SDan Murphy 
185*1c246225SDan Murphy 	return error;
186*1c246225SDan Murphy }
187*1c246225SDan Murphy 
188*1c246225SDan Murphy static void drv2667_worker(struct work_struct *work)
189*1c246225SDan Murphy {
190*1c246225SDan Murphy 	struct drv2667_data *haptics = container_of(work, struct drv2667_data, work);
191*1c246225SDan Murphy 	int error;
192*1c246225SDan Murphy 
193*1c246225SDan Murphy 	if (haptics->magnitude) {
194*1c246225SDan Murphy 		error = regmap_write(haptics->regmap,
195*1c246225SDan Murphy 				DRV2667_PAGE, haptics->page);
196*1c246225SDan Murphy 		if (error) {
197*1c246225SDan Murphy 			dev_err(&haptics->client->dev,
198*1c246225SDan Murphy 				"Failed to set the page: %d\n", error);
199*1c246225SDan Murphy 			return;
200*1c246225SDan Murphy 		}
201*1c246225SDan Murphy 
202*1c246225SDan Murphy 		error = regmap_write(haptics->regmap, DRV2667_RAM_AMP,
203*1c246225SDan Murphy 				haptics->magnitude);
204*1c246225SDan Murphy 		if (error) {
205*1c246225SDan Murphy 			dev_err(&haptics->client->dev,
206*1c246225SDan Murphy 				"Failed to set the amplitude: %d\n", error);
207*1c246225SDan Murphy 			return;
208*1c246225SDan Murphy 		}
209*1c246225SDan Murphy 
210*1c246225SDan Murphy 		error = regmap_write(haptics->regmap,
211*1c246225SDan Murphy 				DRV2667_PAGE, DRV2667_PAGE_0);
212*1c246225SDan Murphy 		if (error) {
213*1c246225SDan Murphy 			dev_err(&haptics->client->dev,
214*1c246225SDan Murphy 				"Failed to set the page: %d\n", error);
215*1c246225SDan Murphy 			return;
216*1c246225SDan Murphy 		}
217*1c246225SDan Murphy 
218*1c246225SDan Murphy 		error = regmap_write(haptics->regmap,
219*1c246225SDan Murphy 				DRV2667_CTRL_2, DRV2667_GO);
220*1c246225SDan Murphy 		if (error) {
221*1c246225SDan Murphy 			dev_err(&haptics->client->dev,
222*1c246225SDan Murphy 				"Failed to set the GO bit: %d\n", error);
223*1c246225SDan Murphy 		}
224*1c246225SDan Murphy 	} else {
225*1c246225SDan Murphy 		error = regmap_update_bits(haptics->regmap, DRV2667_CTRL_2,
226*1c246225SDan Murphy 				DRV2667_GO, 0);
227*1c246225SDan Murphy 		if (error) {
228*1c246225SDan Murphy 			dev_err(&haptics->client->dev,
229*1c246225SDan Murphy 				"Failed to unset the GO bit: %d\n", error);
230*1c246225SDan Murphy 		}
231*1c246225SDan Murphy 	}
232*1c246225SDan Murphy }
233*1c246225SDan Murphy 
234*1c246225SDan Murphy static int drv2667_haptics_play(struct input_dev *input, void *data,
235*1c246225SDan Murphy 				struct ff_effect *effect)
236*1c246225SDan Murphy {
237*1c246225SDan Murphy 	struct drv2667_data *haptics = input_get_drvdata(input);
238*1c246225SDan Murphy 
239*1c246225SDan Murphy 	if (effect->u.rumble.strong_magnitude > 0)
240*1c246225SDan Murphy 		haptics->magnitude = effect->u.rumble.strong_magnitude;
241*1c246225SDan Murphy 	else if (effect->u.rumble.weak_magnitude > 0)
242*1c246225SDan Murphy 		haptics->magnitude = effect->u.rumble.weak_magnitude;
243*1c246225SDan Murphy 	else
244*1c246225SDan Murphy 		haptics->magnitude = 0;
245*1c246225SDan Murphy 
246*1c246225SDan Murphy 	schedule_work(&haptics->work);
247*1c246225SDan Murphy 
248*1c246225SDan Murphy 	return 0;
249*1c246225SDan Murphy }
250*1c246225SDan Murphy 
251*1c246225SDan Murphy static void drv2667_close(struct input_dev *input)
252*1c246225SDan Murphy {
253*1c246225SDan Murphy 	struct drv2667_data *haptics = input_get_drvdata(input);
254*1c246225SDan Murphy 	int error;
255*1c246225SDan Murphy 
256*1c246225SDan Murphy 	cancel_work_sync(&haptics->work);
257*1c246225SDan Murphy 
258*1c246225SDan Murphy 	error = regmap_update_bits(haptics->regmap, DRV2667_CTRL_2,
259*1c246225SDan Murphy 				DRV2667_STANDBY, 1);
260*1c246225SDan Murphy 	if (error)
261*1c246225SDan Murphy 		dev_err(&haptics->client->dev,
262*1c246225SDan Murphy 			"Failed to enter standby mode: %d\n", error);
263*1c246225SDan Murphy }
264*1c246225SDan Murphy 
265*1c246225SDan Murphy static const struct reg_default drv2667_init_regs[] = {
266*1c246225SDan Murphy 	{ DRV2667_CTRL_2, 0 },
267*1c246225SDan Murphy 	{ DRV2667_CTRL_1, DRV2667_25_VPP_GAIN },
268*1c246225SDan Murphy 	{ DRV2667_WV_SEQ_0, 1 },
269*1c246225SDan Murphy 	{ DRV2667_WV_SEQ_1, 0 }
270*1c246225SDan Murphy };
271*1c246225SDan Murphy 
272*1c246225SDan Murphy static const struct reg_default drv2667_page1_init[] = {
273*1c246225SDan Murphy 	{ DRV2667_RAM_HDR_SZ, 0x05 },
274*1c246225SDan Murphy 	{ DRV2667_RAM_START_HI, 0x80 },
275*1c246225SDan Murphy 	{ DRV2667_RAM_START_LO, 0x06 },
276*1c246225SDan Murphy 	{ DRV2667_RAM_STOP_HI, 0x00 },
277*1c246225SDan Murphy 	{ DRV2667_RAM_STOP_LO, 0x09 },
278*1c246225SDan Murphy 	{ DRV2667_RAM_REPEAT_CT, 0 },
279*1c246225SDan Murphy 	{ DRV2667_RAM_DURATION, 0x05 },
280*1c246225SDan Murphy 	{ DRV2667_RAM_ENVELOPE, DRV2667_NO_ENV },
281*1c246225SDan Murphy 	{ DRV2667_RAM_AMP, 0x60 },
282*1c246225SDan Murphy };
283*1c246225SDan Murphy 
284*1c246225SDan Murphy static int drv2667_init(struct drv2667_data *haptics)
285*1c246225SDan Murphy {
286*1c246225SDan Murphy 	int error;
287*1c246225SDan Murphy 
288*1c246225SDan Murphy 	/* Set default haptic frequency to 195Hz on Page 1*/
289*1c246225SDan Murphy 	haptics->frequency = 195;
290*1c246225SDan Murphy 	haptics->page = DRV2667_PAGE_1;
291*1c246225SDan Murphy 
292*1c246225SDan Murphy 	error = regmap_register_patch(haptics->regmap,
293*1c246225SDan Murphy 				      drv2667_init_regs,
294*1c246225SDan Murphy 				      ARRAY_SIZE(drv2667_init_regs));
295*1c246225SDan Murphy 	if (error) {
296*1c246225SDan Murphy 		dev_err(&haptics->client->dev,
297*1c246225SDan Murphy 			"Failed to write init registers: %d\n",
298*1c246225SDan Murphy 			error);
299*1c246225SDan Murphy 		return error;
300*1c246225SDan Murphy 	}
301*1c246225SDan Murphy 
302*1c246225SDan Murphy 	error = regmap_write(haptics->regmap, DRV2667_PAGE, haptics->page);
303*1c246225SDan Murphy 	if (error) {
304*1c246225SDan Murphy 		dev_err(&haptics->client->dev, "Failed to set page: %d\n",
305*1c246225SDan Murphy 			error);
306*1c246225SDan Murphy 		goto error_out;
307*1c246225SDan Murphy 	}
308*1c246225SDan Murphy 
309*1c246225SDan Murphy 	error = drv2667_set_waveform_freq(haptics);
310*1c246225SDan Murphy 	if (error)
311*1c246225SDan Murphy 		goto error_page;
312*1c246225SDan Murphy 
313*1c246225SDan Murphy 	error = regmap_register_patch(haptics->regmap,
314*1c246225SDan Murphy 				      drv2667_page1_init,
315*1c246225SDan Murphy 				      ARRAY_SIZE(drv2667_page1_init));
316*1c246225SDan Murphy 	if (error) {
317*1c246225SDan Murphy 		dev_err(&haptics->client->dev,
318*1c246225SDan Murphy 			"Failed to write page registers: %d\n",
319*1c246225SDan Murphy 			error);
320*1c246225SDan Murphy 		return error;
321*1c246225SDan Murphy 	}
322*1c246225SDan Murphy 
323*1c246225SDan Murphy 	error = regmap_write(haptics->regmap, DRV2667_PAGE, DRV2667_PAGE_0);
324*1c246225SDan Murphy 	return error;
325*1c246225SDan Murphy 
326*1c246225SDan Murphy error_page:
327*1c246225SDan Murphy 	regmap_write(haptics->regmap, DRV2667_PAGE, DRV2667_PAGE_0);
328*1c246225SDan Murphy error_out:
329*1c246225SDan Murphy 	return error;
330*1c246225SDan Murphy }
331*1c246225SDan Murphy 
332*1c246225SDan Murphy static const struct regmap_config drv2667_regmap_config = {
333*1c246225SDan Murphy 	.reg_bits = 8,
334*1c246225SDan Murphy 	.val_bits = 8,
335*1c246225SDan Murphy 
336*1c246225SDan Murphy 	.max_register = DRV2667_MAX_REG,
337*1c246225SDan Murphy 	.reg_defaults = drv2667_reg_defs,
338*1c246225SDan Murphy 	.num_reg_defaults = ARRAY_SIZE(drv2667_reg_defs),
339*1c246225SDan Murphy 	.cache_type = REGCACHE_NONE,
340*1c246225SDan Murphy };
341*1c246225SDan Murphy 
342*1c246225SDan Murphy static int drv2667_probe(struct i2c_client *client,
343*1c246225SDan Murphy 			 const struct i2c_device_id *id)
344*1c246225SDan Murphy {
345*1c246225SDan Murphy 	struct drv2667_data *haptics;
346*1c246225SDan Murphy 	int error;
347*1c246225SDan Murphy 
348*1c246225SDan Murphy 	haptics = devm_kzalloc(&client->dev, sizeof(*haptics), GFP_KERNEL);
349*1c246225SDan Murphy 	if (!haptics)
350*1c246225SDan Murphy 		return -ENOMEM;
351*1c246225SDan Murphy 
352*1c246225SDan Murphy 	haptics->regulator = devm_regulator_get(&client->dev, "vbat");
353*1c246225SDan Murphy 	if (IS_ERR(haptics->regulator)) {
354*1c246225SDan Murphy 		error = PTR_ERR(haptics->regulator);
355*1c246225SDan Murphy 		dev_err(&client->dev,
356*1c246225SDan Murphy 			"unable to get regulator, error: %d\n", error);
357*1c246225SDan Murphy 		return error;
358*1c246225SDan Murphy 	}
359*1c246225SDan Murphy 
360*1c246225SDan Murphy 	haptics->input_dev = devm_input_allocate_device(&client->dev);
361*1c246225SDan Murphy 	if (!haptics->input_dev) {
362*1c246225SDan Murphy 		dev_err(&client->dev, "Failed to allocate input device\n");
363*1c246225SDan Murphy 		return -ENOMEM;
364*1c246225SDan Murphy 	}
365*1c246225SDan Murphy 
366*1c246225SDan Murphy 	haptics->input_dev->name = "drv2667:haptics";
367*1c246225SDan Murphy 	haptics->input_dev->dev.parent = client->dev.parent;
368*1c246225SDan Murphy 	haptics->input_dev->close = drv2667_close;
369*1c246225SDan Murphy 	input_set_drvdata(haptics->input_dev, haptics);
370*1c246225SDan Murphy 	input_set_capability(haptics->input_dev, EV_FF, FF_RUMBLE);
371*1c246225SDan Murphy 
372*1c246225SDan Murphy 	error = input_ff_create_memless(haptics->input_dev, NULL,
373*1c246225SDan Murphy 					drv2667_haptics_play);
374*1c246225SDan Murphy 	if (error) {
375*1c246225SDan Murphy 		dev_err(&client->dev, "input_ff_create() failed: %d\n",
376*1c246225SDan Murphy 			error);
377*1c246225SDan Murphy 		return error;
378*1c246225SDan Murphy 	}
379*1c246225SDan Murphy 
380*1c246225SDan Murphy 	INIT_WORK(&haptics->work, drv2667_worker);
381*1c246225SDan Murphy 
382*1c246225SDan Murphy 	haptics->client = client;
383*1c246225SDan Murphy 	i2c_set_clientdata(client, haptics);
384*1c246225SDan Murphy 
385*1c246225SDan Murphy 	haptics->regmap = devm_regmap_init_i2c(client, &drv2667_regmap_config);
386*1c246225SDan Murphy 	if (IS_ERR(haptics->regmap)) {
387*1c246225SDan Murphy 		error = PTR_ERR(haptics->regmap);
388*1c246225SDan Murphy 		dev_err(&client->dev, "Failed to allocate register map: %d\n",
389*1c246225SDan Murphy 			error);
390*1c246225SDan Murphy 		return error;
391*1c246225SDan Murphy 	}
392*1c246225SDan Murphy 
393*1c246225SDan Murphy 	error = drv2667_init(haptics);
394*1c246225SDan Murphy 	if (error) {
395*1c246225SDan Murphy 		dev_err(&client->dev, "Device init failed: %d\n", error);
396*1c246225SDan Murphy 		return error;
397*1c246225SDan Murphy 	}
398*1c246225SDan Murphy 
399*1c246225SDan Murphy 	error = input_register_device(haptics->input_dev);
400*1c246225SDan Murphy 	if (error) {
401*1c246225SDan Murphy 		dev_err(&client->dev, "couldn't register input device: %d\n",
402*1c246225SDan Murphy 			error);
403*1c246225SDan Murphy 		return error;
404*1c246225SDan Murphy 	}
405*1c246225SDan Murphy 
406*1c246225SDan Murphy 	return 0;
407*1c246225SDan Murphy }
408*1c246225SDan Murphy 
409*1c246225SDan Murphy #ifdef CONFIG_PM_SLEEP
410*1c246225SDan Murphy static int drv2667_suspend(struct device *dev)
411*1c246225SDan Murphy {
412*1c246225SDan Murphy 	struct drv2667_data *haptics = dev_get_drvdata(dev);
413*1c246225SDan Murphy 	int ret = 0;
414*1c246225SDan Murphy 
415*1c246225SDan Murphy 	mutex_lock(&haptics->input_dev->mutex);
416*1c246225SDan Murphy 
417*1c246225SDan Murphy 	if (haptics->input_dev->users) {
418*1c246225SDan Murphy 		ret = regmap_update_bits(haptics->regmap, DRV2667_CTRL_2,
419*1c246225SDan Murphy 				DRV2667_STANDBY, 1);
420*1c246225SDan Murphy 		if (ret) {
421*1c246225SDan Murphy 			dev_err(dev, "Failed to set standby mode\n");
422*1c246225SDan Murphy 			regulator_disable(haptics->regulator);
423*1c246225SDan Murphy 			goto out;
424*1c246225SDan Murphy 		}
425*1c246225SDan Murphy 
426*1c246225SDan Murphy 		ret = regulator_disable(haptics->regulator);
427*1c246225SDan Murphy 		if (ret) {
428*1c246225SDan Murphy 			dev_err(dev, "Failed to disable regulator\n");
429*1c246225SDan Murphy 			regmap_update_bits(haptics->regmap,
430*1c246225SDan Murphy 					   DRV2667_CTRL_2,
431*1c246225SDan Murphy 					   DRV2667_STANDBY, 0);
432*1c246225SDan Murphy 		}
433*1c246225SDan Murphy 	}
434*1c246225SDan Murphy out:
435*1c246225SDan Murphy 	mutex_unlock(&haptics->input_dev->mutex);
436*1c246225SDan Murphy 	return ret;
437*1c246225SDan Murphy }
438*1c246225SDan Murphy 
439*1c246225SDan Murphy static int drv2667_resume(struct device *dev)
440*1c246225SDan Murphy {
441*1c246225SDan Murphy 	struct drv2667_data *haptics = dev_get_drvdata(dev);
442*1c246225SDan Murphy 	int ret = 0;
443*1c246225SDan Murphy 
444*1c246225SDan Murphy 	mutex_lock(&haptics->input_dev->mutex);
445*1c246225SDan Murphy 
446*1c246225SDan Murphy 	if (haptics->input_dev->users) {
447*1c246225SDan Murphy 		ret = regulator_enable(haptics->regulator);
448*1c246225SDan Murphy 		if (ret) {
449*1c246225SDan Murphy 			dev_err(dev, "Failed to enable regulator\n");
450*1c246225SDan Murphy 			goto out;
451*1c246225SDan Murphy 		}
452*1c246225SDan Murphy 
453*1c246225SDan Murphy 		ret = regmap_update_bits(haptics->regmap, DRV2667_CTRL_2,
454*1c246225SDan Murphy 					 DRV2667_STANDBY, 0);
455*1c246225SDan Murphy 		if (ret) {
456*1c246225SDan Murphy 			dev_err(dev, "Failed to unset standby mode\n");
457*1c246225SDan Murphy 			regulator_disable(haptics->regulator);
458*1c246225SDan Murphy 			goto out;
459*1c246225SDan Murphy 		}
460*1c246225SDan Murphy 
461*1c246225SDan Murphy 	}
462*1c246225SDan Murphy 
463*1c246225SDan Murphy out:
464*1c246225SDan Murphy 	mutex_unlock(&haptics->input_dev->mutex);
465*1c246225SDan Murphy 	return ret;
466*1c246225SDan Murphy }
467*1c246225SDan Murphy #endif
468*1c246225SDan Murphy 
469*1c246225SDan Murphy static SIMPLE_DEV_PM_OPS(drv2667_pm_ops, drv2667_suspend, drv2667_resume);
470*1c246225SDan Murphy 
471*1c246225SDan Murphy static const struct i2c_device_id drv2667_id[] = {
472*1c246225SDan Murphy 	{ "drv2667", 0 },
473*1c246225SDan Murphy 	{ }
474*1c246225SDan Murphy };
475*1c246225SDan Murphy MODULE_DEVICE_TABLE(i2c, drv2667_id);
476*1c246225SDan Murphy 
477*1c246225SDan Murphy #ifdef CONFIG_OF
478*1c246225SDan Murphy static const struct of_device_id drv2667_of_match[] = {
479*1c246225SDan Murphy 	{ .compatible = "ti,drv2667", },
480*1c246225SDan Murphy 	{ }
481*1c246225SDan Murphy };
482*1c246225SDan Murphy MODULE_DEVICE_TABLE(of, drv2667_of_match);
483*1c246225SDan Murphy #endif
484*1c246225SDan Murphy 
485*1c246225SDan Murphy static struct i2c_driver drv2667_driver = {
486*1c246225SDan Murphy 	.probe		= drv2667_probe,
487*1c246225SDan Murphy 	.driver		= {
488*1c246225SDan Murphy 		.name	= "drv2667-haptics",
489*1c246225SDan Murphy 		.owner	= THIS_MODULE,
490*1c246225SDan Murphy 		.of_match_table = of_match_ptr(drv2667_of_match),
491*1c246225SDan Murphy 		.pm	= &drv2667_pm_ops,
492*1c246225SDan Murphy 	},
493*1c246225SDan Murphy 	.id_table = drv2667_id,
494*1c246225SDan Murphy };
495*1c246225SDan Murphy module_i2c_driver(drv2667_driver);
496*1c246225SDan Murphy 
497*1c246225SDan Murphy MODULE_ALIAS("platform:drv2667-haptics");
498*1c246225SDan Murphy MODULE_DESCRIPTION("TI DRV2667 haptics driver");
499*1c246225SDan Murphy MODULE_LICENSE("GPL");
500*1c246225SDan Murphy MODULE_AUTHOR("Dan Murphy <dmurphy@ti.com>");
501