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