1 // SPDX-License-Identifier: GPL-2.0-only
3 * Copyright (C) 2011 Sony Ericsson Mobile Communications Inc.
5 * Author: Courtney Cavin <courtney.cavin@sonyericsson.com>
6 * Prepared for up-stream by: Oskar Andero <oskar.andero@sonyericsson.com>
10 #include <linux/irq.h>
11 #include <linux/slab.h>
12 #include <linux/input.h>
13 #include <linux/module.h>
14 #include <linux/interrupt.h>
15 #include <linux/gpio.h>
16 #include <linux/delay.h>
17 #include <linux/input/gp2ap002a00f.h>
20 struct input_dev
*input
;
21 const struct gp2a_platform_data
*pdata
;
22 struct i2c_client
*i2c_client
;
29 GP2A_ADDR_CYCLE
= 0x3,
30 GP2A_ADDR_OPMOD
= 0x4,
35 /* Software Shutdown control: 0 = shutdown, 1 = normal operation */
39 static int gp2a_report(struct gp2a_data
*dt
)
41 int vo
= gpio_get_value(dt
->pdata
->vout_gpio
);
43 input_report_switch(dt
->input
, SW_FRONT_PROXIMITY
, !vo
);
44 input_sync(dt
->input
);
49 static irqreturn_t
gp2a_irq(int irq
, void *handle
)
51 struct gp2a_data
*dt
= handle
;
58 static int gp2a_enable(struct gp2a_data
*dt
)
60 return i2c_smbus_write_byte_data(dt
->i2c_client
, GP2A_ADDR_OPMOD
,
64 static int gp2a_disable(struct gp2a_data
*dt
)
66 return i2c_smbus_write_byte_data(dt
->i2c_client
, GP2A_ADDR_OPMOD
,
70 static int gp2a_device_open(struct input_dev
*dev
)
72 struct gp2a_data
*dt
= input_get_drvdata(dev
);
75 error
= gp2a_enable(dt
);
77 dev_err(&dt
->i2c_client
->dev
,
78 "unable to activate, err %d\n", error
);
87 static void gp2a_device_close(struct input_dev
*dev
)
89 struct gp2a_data
*dt
= input_get_drvdata(dev
);
92 error
= gp2a_disable(dt
);
94 dev_err(&dt
->i2c_client
->dev
,
95 "unable to deactivate, err %d\n", error
);
98 static int gp2a_initialize(struct gp2a_data
*dt
)
102 error
= i2c_smbus_write_byte_data(dt
->i2c_client
, GP2A_ADDR_GAIN
,
107 error
= i2c_smbus_write_byte_data(dt
->i2c_client
, GP2A_ADDR_HYS
,
112 error
= i2c_smbus_write_byte_data(dt
->i2c_client
, GP2A_ADDR_CYCLE
,
117 error
= gp2a_disable(dt
);
122 static int gp2a_probe(struct i2c_client
*client
,
123 const struct i2c_device_id
*id
)
125 const struct gp2a_platform_data
*pdata
= dev_get_platdata(&client
->dev
);
126 struct gp2a_data
*dt
;
132 if (pdata
->hw_setup
) {
133 error
= pdata
->hw_setup(client
);
138 error
= gpio_request_one(pdata
->vout_gpio
, GPIOF_IN
, GP2A_I2C_NAME
);
140 goto err_hw_shutdown
;
142 dt
= kzalloc(sizeof(struct gp2a_data
), GFP_KERNEL
);
149 dt
->i2c_client
= client
;
151 error
= gp2a_initialize(dt
);
155 dt
->input
= input_allocate_device();
161 input_set_drvdata(dt
->input
, dt
);
163 dt
->input
->open
= gp2a_device_open
;
164 dt
->input
->close
= gp2a_device_close
;
165 dt
->input
->name
= GP2A_I2C_NAME
;
166 dt
->input
->id
.bustype
= BUS_I2C
;
167 dt
->input
->dev
.parent
= &client
->dev
;
169 input_set_capability(dt
->input
, EV_SW
, SW_FRONT_PROXIMITY
);
171 error
= request_threaded_irq(client
->irq
, NULL
, gp2a_irq
,
172 IRQF_TRIGGER_RISING
| IRQF_TRIGGER_FALLING
|
176 dev_err(&client
->dev
, "irq request failed\n");
177 goto err_free_input_dev
;
180 error
= input_register_device(dt
->input
);
182 dev_err(&client
->dev
, "device registration failed\n");
186 device_init_wakeup(&client
->dev
, pdata
->wakeup
);
187 i2c_set_clientdata(client
, dt
);
192 free_irq(client
->irq
, dt
);
194 input_free_device(dt
->input
);
198 gpio_free(pdata
->vout_gpio
);
200 if (pdata
->hw_shutdown
)
201 pdata
->hw_shutdown(client
);
205 static int gp2a_remove(struct i2c_client
*client
)
207 struct gp2a_data
*dt
= i2c_get_clientdata(client
);
208 const struct gp2a_platform_data
*pdata
= dt
->pdata
;
210 free_irq(client
->irq
, dt
);
212 input_unregister_device(dt
->input
);
215 gpio_free(pdata
->vout_gpio
);
217 if (pdata
->hw_shutdown
)
218 pdata
->hw_shutdown(client
);
223 static int __maybe_unused
gp2a_suspend(struct device
*dev
)
225 struct i2c_client
*client
= to_i2c_client(dev
);
226 struct gp2a_data
*dt
= i2c_get_clientdata(client
);
229 if (device_may_wakeup(&client
->dev
)) {
230 enable_irq_wake(client
->irq
);
232 mutex_lock(&dt
->input
->mutex
);
233 if (dt
->input
->users
)
234 retval
= gp2a_disable(dt
);
235 mutex_unlock(&dt
->input
->mutex
);
241 static int __maybe_unused
gp2a_resume(struct device
*dev
)
243 struct i2c_client
*client
= to_i2c_client(dev
);
244 struct gp2a_data
*dt
= i2c_get_clientdata(client
);
247 if (device_may_wakeup(&client
->dev
)) {
248 disable_irq_wake(client
->irq
);
250 mutex_lock(&dt
->input
->mutex
);
251 if (dt
->input
->users
)
252 retval
= gp2a_enable(dt
);
253 mutex_unlock(&dt
->input
->mutex
);
259 static SIMPLE_DEV_PM_OPS(gp2a_pm
, gp2a_suspend
, gp2a_resume
);
261 static const struct i2c_device_id gp2a_i2c_id
[] = {
262 { GP2A_I2C_NAME
, 0 },
265 MODULE_DEVICE_TABLE(i2c
, gp2a_i2c_id
);
267 static struct i2c_driver gp2a_i2c_driver
= {
269 .name
= GP2A_I2C_NAME
,
273 .remove
= gp2a_remove
,
274 .id_table
= gp2a_i2c_id
,
277 module_i2c_driver(gp2a_i2c_driver
);
279 MODULE_AUTHOR("Courtney Cavin <courtney.cavin@sonyericsson.com>");
280 MODULE_DESCRIPTION("Sharp GP2AP002A00F I2C Proximity/Opto sensor driver");
281 MODULE_LICENSE("GPL v2");