Merge tag 'v4.15' into next
Sync with mainline to get in trackpoint updates and other changes.
This commit is contained in:
@@ -202,9 +202,9 @@ void gameport_stop_polling(struct gameport *gameport)
|
||||
}
|
||||
EXPORT_SYMBOL(gameport_stop_polling);
|
||||
|
||||
static void gameport_run_poll_handler(unsigned long d)
|
||||
static void gameport_run_poll_handler(struct timer_list *t)
|
||||
{
|
||||
struct gameport *gameport = (struct gameport *)d;
|
||||
struct gameport *gameport = from_timer(gameport, t, poll_timer);
|
||||
|
||||
gameport->poll_handler(gameport);
|
||||
if (gameport->poll_cnt)
|
||||
@@ -542,8 +542,7 @@ static void gameport_init_port(struct gameport *gameport)
|
||||
|
||||
INIT_LIST_HEAD(&gameport->node);
|
||||
spin_lock_init(&gameport->timer_lock);
|
||||
setup_timer(&gameport->poll_timer, gameport_run_poll_handler,
|
||||
(unsigned long)gameport);
|
||||
timer_setup(&gameport->poll_timer, gameport_run_poll_handler, 0);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -2047,7 +2047,7 @@ static void devm_input_device_unregister(struct device *dev, void *res)
|
||||
*/
|
||||
void input_enable_softrepeat(struct input_dev *dev, int delay, int period)
|
||||
{
|
||||
dev->timer.function = (TIMER_FUNC_TYPE)input_repeat_key;
|
||||
dev->timer.function = input_repeat_key;
|
||||
dev->rep[REP_DELAY] = delay;
|
||||
dev->rep[REP_PERIOD] = period;
|
||||
}
|
||||
|
@@ -163,7 +163,7 @@ static unsigned int get_time_pit(void)
|
||||
#define GET_TIME(x) do { x = (unsigned int)rdtsc(); } while (0)
|
||||
#define DELTA(x,y) ((y)-(x))
|
||||
#define TIME_NAME "TSC"
|
||||
#elif defined(__alpha__) || defined(CONFIG_MN10300) || defined(CONFIG_ARM) || defined(CONFIG_ARM64) || defined(CONFIG_TILE)
|
||||
#elif defined(__alpha__) || defined(CONFIG_MN10300) || defined(CONFIG_ARM) || defined(CONFIG_ARM64) || defined(CONFIG_RISCV) || defined(CONFIG_TILE)
|
||||
#define GET_TIME(x) do { x = get_cycles(); } while (0)
|
||||
#define DELTA(x,y) ((y)-(x))
|
||||
#define TIME_NAME "get_cycles"
|
||||
|
@@ -364,9 +364,9 @@ static int db9_saturn(int mode, struct parport *port, struct input_dev *devs[])
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void db9_timer(unsigned long private)
|
||||
static void db9_timer(struct timer_list *t)
|
||||
{
|
||||
struct db9 *db9 = (void *) private;
|
||||
struct db9 *db9 = from_timer(db9, t, timer);
|
||||
struct parport *port = db9->pd->port;
|
||||
struct input_dev *dev = db9->dev[0];
|
||||
struct input_dev *dev2 = db9->dev[1];
|
||||
@@ -609,7 +609,7 @@ static void db9_attach(struct parport *pp)
|
||||
db9->pd = pd;
|
||||
db9->mode = mode;
|
||||
db9->parportno = pp->number;
|
||||
setup_timer(&db9->timer, db9_timer, (long)db9);
|
||||
timer_setup(&db9->timer, db9_timer, 0);
|
||||
|
||||
for (i = 0; i < (min(db9_mode->n_pads, DB9_MAX_DEVICES)); i++) {
|
||||
|
||||
|
@@ -743,9 +743,9 @@ static void gc_psx_process_packet(struct gc *gc)
|
||||
* gc_timer() initiates reads of console pads data.
|
||||
*/
|
||||
|
||||
static void gc_timer(unsigned long private)
|
||||
static void gc_timer(struct timer_list *t)
|
||||
{
|
||||
struct gc *gc = (void *) private;
|
||||
struct gc *gc = from_timer(gc, t, timer);
|
||||
|
||||
/*
|
||||
* N64 pads - must be read first, any read confuses them for 200 us
|
||||
@@ -974,7 +974,7 @@ static void gc_attach(struct parport *pp)
|
||||
mutex_init(&gc->mutex);
|
||||
gc->pd = pd;
|
||||
gc->parportno = pp->number;
|
||||
setup_timer(&gc->timer, gc_timer, (long) gc);
|
||||
timer_setup(&gc->timer, gc_timer, 0);
|
||||
|
||||
for (i = 0; i < n_pads && i < GC_MAX_DEVICES; i++) {
|
||||
if (!pads[i])
|
||||
|
@@ -89,9 +89,9 @@ static struct tgfx {
|
||||
* tgfx_timer() reads and analyzes TurboGraFX joystick data.
|
||||
*/
|
||||
|
||||
static void tgfx_timer(unsigned long private)
|
||||
static void tgfx_timer(struct timer_list *t)
|
||||
{
|
||||
struct tgfx *tgfx = (void *) private;
|
||||
struct tgfx *tgfx = from_timer(tgfx, t, timer);
|
||||
struct input_dev *dev;
|
||||
int data1, data2, i;
|
||||
|
||||
@@ -200,7 +200,7 @@ static void tgfx_attach(struct parport *pp)
|
||||
mutex_init(&tgfx->sem);
|
||||
tgfx->pd = pd;
|
||||
tgfx->parportno = pp->number;
|
||||
setup_timer(&tgfx->timer, tgfx_timer, (long)tgfx);
|
||||
timer_setup(&tgfx->timer, tgfx_timer, 0);
|
||||
|
||||
for (i = 0; i < n_devs; i++) {
|
||||
if (n_buttons[i] < 1)
|
||||
|
@@ -226,6 +226,7 @@ static const struct xpad_device {
|
||||
{ 0x0e6f, 0x0213, "Afterglow Gamepad for Xbox 360", 0, XTYPE_XBOX360 },
|
||||
{ 0x0e6f, 0x021f, "Rock Candy Gamepad for Xbox 360", 0, XTYPE_XBOX360 },
|
||||
{ 0x0e6f, 0x0246, "Rock Candy Gamepad for Xbox One 2015", 0, XTYPE_XBOXONE },
|
||||
{ 0x0e6f, 0x02ab, "PDP Controller for Xbox One", 0, XTYPE_XBOXONE },
|
||||
{ 0x0e6f, 0x0301, "Logic3 Controller", 0, XTYPE_XBOX360 },
|
||||
{ 0x0e6f, 0x0346, "Rock Candy Gamepad for Xbox One 2016", 0, XTYPE_XBOXONE },
|
||||
{ 0x0e6f, 0x0401, "Logic3 Controller", 0, XTYPE_XBOX360 },
|
||||
@@ -472,6 +473,22 @@ static const u8 xboxone_hori_init[] = {
|
||||
0x00, 0x00, 0x00, 0x80, 0x00
|
||||
};
|
||||
|
||||
/*
|
||||
* This packet is required for some of the PDP pads to start
|
||||
* sending input reports. One of those pads is (0x0e6f:0x02ab).
|
||||
*/
|
||||
static const u8 xboxone_pdp_init1[] = {
|
||||
0x0a, 0x20, 0x00, 0x03, 0x00, 0x01, 0x14
|
||||
};
|
||||
|
||||
/*
|
||||
* This packet is required for some of the PDP pads to start
|
||||
* sending input reports. One of those pads is (0x0e6f:0x02ab).
|
||||
*/
|
||||
static const u8 xboxone_pdp_init2[] = {
|
||||
0x06, 0x20, 0x00, 0x02, 0x01, 0x00
|
||||
};
|
||||
|
||||
/*
|
||||
* A specific rumble packet is required for some PowerA pads to start
|
||||
* sending input reports. One of those pads is (0x24c6:0x543a).
|
||||
@@ -502,6 +519,8 @@ static const struct xboxone_init_packet xboxone_init_packets[] = {
|
||||
XBOXONE_INIT_PKT(0x0e6f, 0x0165, xboxone_hori_init),
|
||||
XBOXONE_INIT_PKT(0x0f0d, 0x0067, xboxone_hori_init),
|
||||
XBOXONE_INIT_PKT(0x0000, 0x0000, xboxone_fw2015_init),
|
||||
XBOXONE_INIT_PKT(0x0e6f, 0x02ab, xboxone_pdp_init1),
|
||||
XBOXONE_INIT_PKT(0x0e6f, 0x02ab, xboxone_pdp_init2),
|
||||
XBOXONE_INIT_PKT(0x24c6, 0x541a, xboxone_rumblebegin_init),
|
||||
XBOXONE_INIT_PKT(0x24c6, 0x542a, xboxone_rumblebegin_init),
|
||||
XBOXONE_INIT_PKT(0x24c6, 0x543a, xboxone_rumblebegin_init),
|
||||
|
@@ -1651,7 +1651,7 @@ ims_pcu_get_cdc_union_desc(struct usb_interface *intf)
|
||||
return union_desc;
|
||||
|
||||
dev_err(&intf->dev,
|
||||
"Union descriptor to short (%d vs %zd\n)",
|
||||
"Union descriptor too short (%d vs %zd)\n",
|
||||
union_desc->bLength, sizeof(*union_desc));
|
||||
return NULL;
|
||||
}
|
||||
|
@@ -233,7 +233,7 @@ static int __maybe_unused regulator_haptic_resume(struct device *dev)
|
||||
|
||||
haptic->suspended = false;
|
||||
|
||||
magnitude = ACCESS_ONCE(haptic->magnitude);
|
||||
magnitude = READ_ONCE(haptic->magnitude);
|
||||
if (magnitude)
|
||||
regulator_haptic_set_voltage(haptic, magnitude);
|
||||
|
||||
|
@@ -178,12 +178,14 @@ static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops,
|
||||
twl4030_vibra_suspend, twl4030_vibra_resume);
|
||||
|
||||
static bool twl4030_vibra_check_coexist(struct twl4030_vibra_data *pdata,
|
||||
struct device_node *node)
|
||||
struct device_node *parent)
|
||||
{
|
||||
struct device_node *node;
|
||||
|
||||
if (pdata && pdata->coexist)
|
||||
return true;
|
||||
|
||||
node = of_find_node_by_name(node, "codec");
|
||||
node = of_get_child_by_name(parent, "codec");
|
||||
if (node) {
|
||||
of_node_put(node);
|
||||
return true;
|
||||
|
@@ -248,8 +248,7 @@ static int twl6040_vibra_probe(struct platform_device *pdev)
|
||||
int vddvibr_uV = 0;
|
||||
int error;
|
||||
|
||||
of_node_get(twl6040_core_dev->of_node);
|
||||
twl6040_core_node = of_find_node_by_name(twl6040_core_dev->of_node,
|
||||
twl6040_core_node = of_get_child_by_name(twl6040_core_dev->of_node,
|
||||
"vibra");
|
||||
if (!twl6040_core_node) {
|
||||
dev_err(&pdev->dev, "parent of node is missing?\n");
|
||||
|
@@ -326,8 +326,6 @@ static int xenkbd_probe(struct xenbus_device *dev,
|
||||
0, width, 0, 0);
|
||||
input_set_abs_params(mtouch, ABS_MT_POSITION_Y,
|
||||
0, height, 0, 0);
|
||||
input_set_abs_params(mtouch, ABS_MT_PRESSURE,
|
||||
0, 255, 0, 0);
|
||||
|
||||
ret = input_mt_init_slots(mtouch, num_cont, INPUT_MT_DIRECT);
|
||||
if (ret) {
|
||||
|
@@ -1250,29 +1250,32 @@ static int alps_decode_ss4_v2(struct alps_fields *f,
|
||||
case SS4_PACKET_ID_MULTI:
|
||||
if (priv->flags & ALPS_BUTTONPAD) {
|
||||
if (IS_SS4PLUS_DEV(priv->dev_id)) {
|
||||
f->mt[0].x = SS4_PLUS_BTL_MF_X_V2(p, 0);
|
||||
f->mt[1].x = SS4_PLUS_BTL_MF_X_V2(p, 1);
|
||||
f->mt[2].x = SS4_PLUS_BTL_MF_X_V2(p, 0);
|
||||
f->mt[3].x = SS4_PLUS_BTL_MF_X_V2(p, 1);
|
||||
no_data_x = SS4_PLUS_MFPACKET_NO_AX_BL;
|
||||
} else {
|
||||
f->mt[2].x = SS4_BTL_MF_X_V2(p, 0);
|
||||
f->mt[3].x = SS4_BTL_MF_X_V2(p, 1);
|
||||
no_data_x = SS4_MFPACKET_NO_AX_BL;
|
||||
}
|
||||
no_data_y = SS4_MFPACKET_NO_AY_BL;
|
||||
|
||||
f->mt[2].y = SS4_BTL_MF_Y_V2(p, 0);
|
||||
f->mt[3].y = SS4_BTL_MF_Y_V2(p, 1);
|
||||
no_data_x = SS4_MFPACKET_NO_AX_BL;
|
||||
no_data_y = SS4_MFPACKET_NO_AY_BL;
|
||||
} else {
|
||||
if (IS_SS4PLUS_DEV(priv->dev_id)) {
|
||||
f->mt[0].x = SS4_PLUS_STD_MF_X_V2(p, 0);
|
||||
f->mt[1].x = SS4_PLUS_STD_MF_X_V2(p, 1);
|
||||
f->mt[2].x = SS4_PLUS_STD_MF_X_V2(p, 0);
|
||||
f->mt[3].x = SS4_PLUS_STD_MF_X_V2(p, 1);
|
||||
no_data_x = SS4_PLUS_MFPACKET_NO_AX;
|
||||
} else {
|
||||
f->mt[0].x = SS4_STD_MF_X_V2(p, 0);
|
||||
f->mt[1].x = SS4_STD_MF_X_V2(p, 1);
|
||||
f->mt[2].x = SS4_STD_MF_X_V2(p, 0);
|
||||
f->mt[3].x = SS4_STD_MF_X_V2(p, 1);
|
||||
no_data_x = SS4_MFPACKET_NO_AX;
|
||||
}
|
||||
no_data_y = SS4_MFPACKET_NO_AY;
|
||||
|
||||
f->mt[2].y = SS4_STD_MF_Y_V2(p, 0);
|
||||
f->mt[3].y = SS4_STD_MF_Y_V2(p, 1);
|
||||
no_data_x = SS4_MFPACKET_NO_AX;
|
||||
no_data_y = SS4_MFPACKET_NO_AY;
|
||||
}
|
||||
|
||||
f->first_mp = 0;
|
||||
|
@@ -141,10 +141,12 @@ enum SS4_PACKET_ID {
|
||||
#define SS4_TS_Z_V2(_b) (s8)(_b[4] & 0x7F)
|
||||
|
||||
|
||||
#define SS4_MFPACKET_NO_AX 8160 /* X-Coordinate value */
|
||||
#define SS4_MFPACKET_NO_AY 4080 /* Y-Coordinate value */
|
||||
#define SS4_MFPACKET_NO_AX_BL 8176 /* Buttonless X-Coordinate value */
|
||||
#define SS4_MFPACKET_NO_AY_BL 4088 /* Buttonless Y-Coordinate value */
|
||||
#define SS4_MFPACKET_NO_AX 8160 /* X-Coordinate value */
|
||||
#define SS4_MFPACKET_NO_AY 4080 /* Y-Coordinate value */
|
||||
#define SS4_MFPACKET_NO_AX_BL 8176 /* Buttonless X-Coord value */
|
||||
#define SS4_MFPACKET_NO_AY_BL 4088 /* Buttonless Y-Coord value */
|
||||
#define SS4_PLUS_MFPACKET_NO_AX 4080 /* SS4 PLUS, X */
|
||||
#define SS4_PLUS_MFPACKET_NO_AX_BL 4088 /* Buttonless SS4 PLUS, X */
|
||||
|
||||
/*
|
||||
* enum V7_PACKET_ID - defines the packet type for V7
|
||||
|
@@ -1260,6 +1260,7 @@ static const struct acpi_device_id elan_acpi_id[] = {
|
||||
{ "ELAN0608", 0 },
|
||||
{ "ELAN0609", 0 },
|
||||
{ "ELAN060B", 0 },
|
||||
{ "ELAN060C", 0 },
|
||||
{ "ELAN0611", 0 },
|
||||
{ "ELAN1000", 0 },
|
||||
{ }
|
||||
|
@@ -1613,7 +1613,7 @@ static int elantech_set_properties(struct elantech_data *etd)
|
||||
case 5:
|
||||
etd->hw_version = 3;
|
||||
break;
|
||||
case 6 ... 14:
|
||||
case 6 ... 15:
|
||||
etd->hw_version = 4;
|
||||
break;
|
||||
default:
|
||||
|
@@ -173,6 +173,7 @@ static const char * const smbus_pnp_ids[] = {
|
||||
"LEN0046", /* X250 */
|
||||
"LEN004a", /* W541 */
|
||||
"LEN200f", /* T450s */
|
||||
"LEN2018", /* T460p */
|
||||
NULL
|
||||
};
|
||||
|
||||
|
@@ -19,6 +19,13 @@
|
||||
#include "psmouse.h"
|
||||
#include "trackpoint.h"
|
||||
|
||||
static const char * const trackpoint_variants[] = {
|
||||
[TP_VARIANT_IBM] = "IBM",
|
||||
[TP_VARIANT_ALPS] = "ALPS",
|
||||
[TP_VARIANT_ELAN] = "Elan",
|
||||
[TP_VARIANT_NXP] = "NXP",
|
||||
};
|
||||
|
||||
/*
|
||||
* Power-on Reset: Resets all trackpoint parameters, including RAM values,
|
||||
* to defaults.
|
||||
@@ -26,7 +33,7 @@
|
||||
*/
|
||||
static int trackpoint_power_on_reset(struct ps2dev *ps2dev)
|
||||
{
|
||||
unsigned char results[2];
|
||||
u8 results[2];
|
||||
int tries = 0;
|
||||
|
||||
/* Issue POR command, and repeat up to once if 0xFC00 received */
|
||||
@@ -38,7 +45,7 @@ static int trackpoint_power_on_reset(struct ps2dev *ps2dev)
|
||||
|
||||
/* Check for success response -- 0xAA00 */
|
||||
if (results[0] != 0xAA || results[1] != 0x00)
|
||||
return -1;
|
||||
return -ENODEV;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -46,8 +53,7 @@ static int trackpoint_power_on_reset(struct ps2dev *ps2dev)
|
||||
/*
|
||||
* Device IO: read, write and toggle bit
|
||||
*/
|
||||
static int trackpoint_read(struct ps2dev *ps2dev,
|
||||
unsigned char loc, unsigned char *results)
|
||||
static int trackpoint_read(struct ps2dev *ps2dev, u8 loc, u8 *results)
|
||||
{
|
||||
if (ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND)) ||
|
||||
ps2_command(ps2dev, results, MAKE_PS2_CMD(0, 1, loc))) {
|
||||
@@ -57,8 +63,7 @@ static int trackpoint_read(struct ps2dev *ps2dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int trackpoint_write(struct ps2dev *ps2dev,
|
||||
unsigned char loc, unsigned char val)
|
||||
static int trackpoint_write(struct ps2dev *ps2dev, u8 loc, u8 val)
|
||||
{
|
||||
if (ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_COMMAND)) ||
|
||||
ps2_command(ps2dev, NULL, MAKE_PS2_CMD(0, 0, TP_WRITE_MEM)) ||
|
||||
@@ -70,8 +75,7 @@ static int trackpoint_write(struct ps2dev *ps2dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int trackpoint_toggle_bit(struct ps2dev *ps2dev,
|
||||
unsigned char loc, unsigned char mask)
|
||||
static int trackpoint_toggle_bit(struct ps2dev *ps2dev, u8 loc, u8 mask)
|
||||
{
|
||||
/* Bad things will happen if the loc param isn't in this range */
|
||||
if (loc < 0x20 || loc >= 0x2F)
|
||||
@@ -87,11 +91,11 @@ static int trackpoint_toggle_bit(struct ps2dev *ps2dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int trackpoint_update_bit(struct ps2dev *ps2dev, unsigned char loc,
|
||||
unsigned char mask, unsigned char value)
|
||||
static int trackpoint_update_bit(struct ps2dev *ps2dev,
|
||||
u8 loc, u8 mask, u8 value)
|
||||
{
|
||||
int retval = 0;
|
||||
unsigned char data;
|
||||
u8 data;
|
||||
|
||||
trackpoint_read(ps2dev, loc, &data);
|
||||
if (((data & mask) == mask) != !!value)
|
||||
@@ -105,17 +109,18 @@ static int trackpoint_update_bit(struct ps2dev *ps2dev, unsigned char loc,
|
||||
*/
|
||||
struct trackpoint_attr_data {
|
||||
size_t field_offset;
|
||||
unsigned char command;
|
||||
unsigned char mask;
|
||||
unsigned char inverted;
|
||||
unsigned char power_on_default;
|
||||
u8 command;
|
||||
u8 mask;
|
||||
bool inverted;
|
||||
u8 power_on_default;
|
||||
};
|
||||
|
||||
static ssize_t trackpoint_show_int_attr(struct psmouse *psmouse, void *data, char *buf)
|
||||
static ssize_t trackpoint_show_int_attr(struct psmouse *psmouse,
|
||||
void *data, char *buf)
|
||||
{
|
||||
struct trackpoint_data *tp = psmouse->private;
|
||||
struct trackpoint_attr_data *attr = data;
|
||||
unsigned char value = *(unsigned char *)((char *)tp + attr->field_offset);
|
||||
u8 value = *(u8 *)((void *)tp + attr->field_offset);
|
||||
|
||||
if (attr->inverted)
|
||||
value = !value;
|
||||
@@ -128,8 +133,8 @@ static ssize_t trackpoint_set_int_attr(struct psmouse *psmouse, void *data,
|
||||
{
|
||||
struct trackpoint_data *tp = psmouse->private;
|
||||
struct trackpoint_attr_data *attr = data;
|
||||
unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset);
|
||||
unsigned char value;
|
||||
u8 *field = (void *)tp + attr->field_offset;
|
||||
u8 value;
|
||||
int err;
|
||||
|
||||
err = kstrtou8(buf, 10, &value);
|
||||
@@ -157,17 +162,14 @@ static ssize_t trackpoint_set_bit_attr(struct psmouse *psmouse, void *data,
|
||||
{
|
||||
struct trackpoint_data *tp = psmouse->private;
|
||||
struct trackpoint_attr_data *attr = data;
|
||||
unsigned char *field = (unsigned char *)((char *)tp + attr->field_offset);
|
||||
unsigned int value;
|
||||
bool *field = (void *)tp + attr->field_offset;
|
||||
bool value;
|
||||
int err;
|
||||
|
||||
err = kstrtouint(buf, 10, &value);
|
||||
err = kstrtobool(buf, &value);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
if (value > 1)
|
||||
return -EINVAL;
|
||||
|
||||
if (attr->inverted)
|
||||
value = !value;
|
||||
|
||||
@@ -193,30 +195,6 @@ PSMOUSE_DEFINE_ATTR(_name, S_IWUSR | S_IRUGO, \
|
||||
&trackpoint_attr_##_name, \
|
||||
trackpoint_show_int_attr, trackpoint_set_bit_attr)
|
||||
|
||||
#define TRACKPOINT_UPDATE_BIT(_psmouse, _tp, _name) \
|
||||
do { \
|
||||
struct trackpoint_attr_data *_attr = &trackpoint_attr_##_name; \
|
||||
\
|
||||
trackpoint_update_bit(&_psmouse->ps2dev, \
|
||||
_attr->command, _attr->mask, _tp->_name); \
|
||||
} while (0)
|
||||
|
||||
#define TRACKPOINT_UPDATE(_power_on, _psmouse, _tp, _name) \
|
||||
do { \
|
||||
if (!_power_on || \
|
||||
_tp->_name != trackpoint_attr_##_name.power_on_default) { \
|
||||
if (!trackpoint_attr_##_name.mask) \
|
||||
trackpoint_write(&_psmouse->ps2dev, \
|
||||
trackpoint_attr_##_name.command, \
|
||||
_tp->_name); \
|
||||
else \
|
||||
TRACKPOINT_UPDATE_BIT(_psmouse, _tp, _name); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define TRACKPOINT_SET_POWER_ON_DEFAULT(_tp, _name) \
|
||||
(_tp->_name = trackpoint_attr_##_name.power_on_default)
|
||||
|
||||
TRACKPOINT_INT_ATTR(sensitivity, TP_SENS, TP_DEF_SENS);
|
||||
TRACKPOINT_INT_ATTR(speed, TP_SPEED, TP_DEF_SPEED);
|
||||
TRACKPOINT_INT_ATTR(inertia, TP_INERTIA, TP_DEF_INERTIA);
|
||||
@@ -229,13 +207,33 @@ TRACKPOINT_INT_ATTR(ztime, TP_Z_TIME, TP_DEF_Z_TIME);
|
||||
TRACKPOINT_INT_ATTR(jenks, TP_JENKS_CURV, TP_DEF_JENKS_CURV);
|
||||
TRACKPOINT_INT_ATTR(drift_time, TP_DRIFT_TIME, TP_DEF_DRIFT_TIME);
|
||||
|
||||
TRACKPOINT_BIT_ATTR(press_to_select, TP_TOGGLE_PTSON, TP_MASK_PTSON, 0,
|
||||
TRACKPOINT_BIT_ATTR(press_to_select, TP_TOGGLE_PTSON, TP_MASK_PTSON, false,
|
||||
TP_DEF_PTSON);
|
||||
TRACKPOINT_BIT_ATTR(skipback, TP_TOGGLE_SKIPBACK, TP_MASK_SKIPBACK, 0,
|
||||
TRACKPOINT_BIT_ATTR(skipback, TP_TOGGLE_SKIPBACK, TP_MASK_SKIPBACK, false,
|
||||
TP_DEF_SKIPBACK);
|
||||
TRACKPOINT_BIT_ATTR(ext_dev, TP_TOGGLE_EXT_DEV, TP_MASK_EXT_DEV, 1,
|
||||
TRACKPOINT_BIT_ATTR(ext_dev, TP_TOGGLE_EXT_DEV, TP_MASK_EXT_DEV, true,
|
||||
TP_DEF_EXT_DEV);
|
||||
|
||||
static bool trackpoint_is_attr_available(struct psmouse *psmouse,
|
||||
struct attribute *attr)
|
||||
{
|
||||
struct trackpoint_data *tp = psmouse->private;
|
||||
|
||||
return tp->variant_id == TP_VARIANT_IBM ||
|
||||
attr == &psmouse_attr_sensitivity.dattr.attr ||
|
||||
attr == &psmouse_attr_press_to_select.dattr.attr;
|
||||
}
|
||||
|
||||
static umode_t trackpoint_is_attr_visible(struct kobject *kobj,
|
||||
struct attribute *attr, int n)
|
||||
{
|
||||
struct device *dev = container_of(kobj, struct device, kobj);
|
||||
struct serio *serio = to_serio_port(dev);
|
||||
struct psmouse *psmouse = serio_get_drvdata(serio);
|
||||
|
||||
return trackpoint_is_attr_available(psmouse, attr) ? attr->mode : 0;
|
||||
}
|
||||
|
||||
static struct attribute *trackpoint_attrs[] = {
|
||||
&psmouse_attr_sensitivity.dattr.attr,
|
||||
&psmouse_attr_speed.dattr.attr,
|
||||
@@ -255,24 +253,56 @@ static struct attribute *trackpoint_attrs[] = {
|
||||
};
|
||||
|
||||
static struct attribute_group trackpoint_attr_group = {
|
||||
.attrs = trackpoint_attrs,
|
||||
.is_visible = trackpoint_is_attr_visible,
|
||||
.attrs = trackpoint_attrs,
|
||||
};
|
||||
|
||||
static int trackpoint_start_protocol(struct psmouse *psmouse, unsigned char *firmware_id)
|
||||
#define TRACKPOINT_UPDATE(_power_on, _psmouse, _tp, _name) \
|
||||
do { \
|
||||
struct trackpoint_attr_data *_attr = &trackpoint_attr_##_name; \
|
||||
\
|
||||
if ((!_power_on || _tp->_name != _attr->power_on_default) && \
|
||||
trackpoint_is_attr_available(_psmouse, \
|
||||
&psmouse_attr_##_name.dattr.attr)) { \
|
||||
if (!_attr->mask) \
|
||||
trackpoint_write(&_psmouse->ps2dev, \
|
||||
_attr->command, _tp->_name); \
|
||||
else \
|
||||
trackpoint_update_bit(&_psmouse->ps2dev, \
|
||||
_attr->command, _attr->mask, \
|
||||
_tp->_name); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define TRACKPOINT_SET_POWER_ON_DEFAULT(_tp, _name) \
|
||||
do { \
|
||||
_tp->_name = trackpoint_attr_##_name.power_on_default; \
|
||||
} while (0)
|
||||
|
||||
static int trackpoint_start_protocol(struct psmouse *psmouse,
|
||||
u8 *variant_id, u8 *firmware_id)
|
||||
{
|
||||
unsigned char param[2] = { 0 };
|
||||
u8 param[2] = { 0 };
|
||||
int error;
|
||||
|
||||
if (ps2_command(&psmouse->ps2dev, param, MAKE_PS2_CMD(0, 2, TP_READ_ID)))
|
||||
return -1;
|
||||
error = ps2_command(&psmouse->ps2dev,
|
||||
param, MAKE_PS2_CMD(0, 2, TP_READ_ID));
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
/* add new TP ID. */
|
||||
if (!(param[0] & TP_MAGIC_IDENT))
|
||||
return -1;
|
||||
switch (param[0]) {
|
||||
case TP_VARIANT_IBM:
|
||||
case TP_VARIANT_ALPS:
|
||||
case TP_VARIANT_ELAN:
|
||||
case TP_VARIANT_NXP:
|
||||
if (variant_id)
|
||||
*variant_id = param[0];
|
||||
if (firmware_id)
|
||||
*firmware_id = param[1];
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (firmware_id)
|
||||
*firmware_id = param[1];
|
||||
|
||||
return 0;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -285,7 +315,7 @@ static int trackpoint_sync(struct psmouse *psmouse, bool in_power_on_state)
|
||||
{
|
||||
struct trackpoint_data *tp = psmouse->private;
|
||||
|
||||
if (!in_power_on_state) {
|
||||
if (!in_power_on_state && tp->variant_id == TP_VARIANT_IBM) {
|
||||
/*
|
||||
* Disable features that may make device unusable
|
||||
* with this driver.
|
||||
@@ -347,7 +377,8 @@ static void trackpoint_defaults(struct trackpoint_data *tp)
|
||||
|
||||
static void trackpoint_disconnect(struct psmouse *psmouse)
|
||||
{
|
||||
sysfs_remove_group(&psmouse->ps2dev.serio->dev.kobj, &trackpoint_attr_group);
|
||||
device_remove_group(&psmouse->ps2dev.serio->dev,
|
||||
&trackpoint_attr_group);
|
||||
|
||||
kfree(psmouse->private);
|
||||
psmouse->private = NULL;
|
||||
@@ -355,14 +386,20 @@ static void trackpoint_disconnect(struct psmouse *psmouse)
|
||||
|
||||
static int trackpoint_reconnect(struct psmouse *psmouse)
|
||||
{
|
||||
int reset_fail;
|
||||
struct trackpoint_data *tp = psmouse->private;
|
||||
int error;
|
||||
bool was_reset;
|
||||
|
||||
if (trackpoint_start_protocol(psmouse, NULL))
|
||||
return -1;
|
||||
error = trackpoint_start_protocol(psmouse, NULL, NULL);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
reset_fail = trackpoint_power_on_reset(&psmouse->ps2dev);
|
||||
if (trackpoint_sync(psmouse, !reset_fail))
|
||||
return -1;
|
||||
was_reset = tp->variant_id == TP_VARIANT_IBM &&
|
||||
trackpoint_power_on_reset(&psmouse->ps2dev) == 0;
|
||||
|
||||
error = trackpoint_sync(psmouse, was_reset);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -370,46 +407,66 @@ static int trackpoint_reconnect(struct psmouse *psmouse)
|
||||
int trackpoint_detect(struct psmouse *psmouse, bool set_properties)
|
||||
{
|
||||
struct ps2dev *ps2dev = &psmouse->ps2dev;
|
||||
unsigned char firmware_id;
|
||||
unsigned char button_info;
|
||||
struct trackpoint_data *tp;
|
||||
u8 variant_id;
|
||||
u8 firmware_id;
|
||||
u8 button_info;
|
||||
int error;
|
||||
|
||||
if (trackpoint_start_protocol(psmouse, &firmware_id))
|
||||
return -1;
|
||||
error = trackpoint_start_protocol(psmouse, &variant_id, &firmware_id);
|
||||
if (error)
|
||||
return error;
|
||||
|
||||
if (!set_properties)
|
||||
return 0;
|
||||
|
||||
if (trackpoint_read(ps2dev, TP_EXT_BTN, &button_info)) {
|
||||
psmouse_warn(psmouse, "failed to get extended button data, assuming 3 buttons\n");
|
||||
button_info = 0x33;
|
||||
}
|
||||
|
||||
psmouse->private = kzalloc(sizeof(struct trackpoint_data), GFP_KERNEL);
|
||||
if (!psmouse->private)
|
||||
tp = kzalloc(sizeof(*tp), GFP_KERNEL);
|
||||
if (!tp)
|
||||
return -ENOMEM;
|
||||
|
||||
psmouse->vendor = "IBM";
|
||||
trackpoint_defaults(tp);
|
||||
tp->variant_id = variant_id;
|
||||
tp->firmware_id = firmware_id;
|
||||
|
||||
psmouse->private = tp;
|
||||
|
||||
psmouse->vendor = trackpoint_variants[variant_id];
|
||||
psmouse->name = "TrackPoint";
|
||||
|
||||
psmouse->reconnect = trackpoint_reconnect;
|
||||
psmouse->disconnect = trackpoint_disconnect;
|
||||
|
||||
if (variant_id != TP_VARIANT_IBM) {
|
||||
/* Newer variants do not support extended button query. */
|
||||
button_info = 0x33;
|
||||
} else {
|
||||
error = trackpoint_read(ps2dev, TP_EXT_BTN, &button_info);
|
||||
if (error) {
|
||||
psmouse_warn(psmouse,
|
||||
"failed to get extended button data, assuming 3 buttons\n");
|
||||
button_info = 0x33;
|
||||
} else if (!button_info) {
|
||||
psmouse_warn(psmouse,
|
||||
"got 0 in extended button data, assuming 3 buttons\n");
|
||||
button_info = 0x33;
|
||||
}
|
||||
}
|
||||
|
||||
if ((button_info & 0x0f) >= 3)
|
||||
__set_bit(BTN_MIDDLE, psmouse->dev->keybit);
|
||||
input_set_capability(psmouse->dev, EV_KEY, BTN_MIDDLE);
|
||||
|
||||
__set_bit(INPUT_PROP_POINTER, psmouse->dev->propbit);
|
||||
__set_bit(INPUT_PROP_POINTING_STICK, psmouse->dev->propbit);
|
||||
|
||||
trackpoint_defaults(psmouse->private);
|
||||
|
||||
error = trackpoint_power_on_reset(ps2dev);
|
||||
|
||||
/* Write defaults to TP only if reset fails. */
|
||||
if (error)
|
||||
if (variant_id != TP_VARIANT_IBM ||
|
||||
trackpoint_power_on_reset(ps2dev) != 0) {
|
||||
/*
|
||||
* Write defaults to TP if we did not reset the trackpoint.
|
||||
*/
|
||||
trackpoint_sync(psmouse, false);
|
||||
}
|
||||
|
||||
error = sysfs_create_group(&ps2dev->serio->dev.kobj, &trackpoint_attr_group);
|
||||
error = device_add_group(&ps2dev->serio->dev, &trackpoint_attr_group);
|
||||
if (error) {
|
||||
psmouse_err(psmouse,
|
||||
"failed to create sysfs attributes, error: %d\n",
|
||||
@@ -420,8 +477,8 @@ int trackpoint_detect(struct psmouse *psmouse, bool set_properties)
|
||||
}
|
||||
|
||||
psmouse_info(psmouse,
|
||||
"IBM TrackPoint firmware: 0x%02x, buttons: %d/%d\n",
|
||||
firmware_id,
|
||||
"%s TrackPoint firmware: 0x%02x, buttons: %d/%d\n",
|
||||
psmouse->vendor, firmware_id,
|
||||
(button_info & 0xf0) >> 4, button_info & 0x0f);
|
||||
|
||||
return 0;
|
||||
|
@@ -21,10 +21,16 @@
|
||||
#define TP_COMMAND 0xE2 /* Commands start with this */
|
||||
|
||||
#define TP_READ_ID 0xE1 /* Sent for device identification */
|
||||
#define TP_MAGIC_IDENT 0x03 /* Sent after a TP_READ_ID followed */
|
||||
/* by the firmware ID */
|
||||
/* Firmware ID includes 0x1, 0x2, 0x3 */
|
||||
|
||||
/*
|
||||
* Valid first byte responses to the "Read Secondary ID" (0xE1) command.
|
||||
* 0x01 was the original IBM trackpoint, others implement very limited
|
||||
* subset of trackpoint features.
|
||||
*/
|
||||
#define TP_VARIANT_IBM 0x01
|
||||
#define TP_VARIANT_ALPS 0x02
|
||||
#define TP_VARIANT_ELAN 0x03
|
||||
#define TP_VARIANT_NXP 0x04
|
||||
|
||||
/*
|
||||
* Commands
|
||||
@@ -136,18 +142,20 @@
|
||||
|
||||
#define MAKE_PS2_CMD(params, results, cmd) ((params<<12) | (results<<8) | (cmd))
|
||||
|
||||
struct trackpoint_data
|
||||
{
|
||||
unsigned char sensitivity, speed, inertia, reach;
|
||||
unsigned char draghys, mindrag;
|
||||
unsigned char thresh, upthresh;
|
||||
unsigned char ztime, jenks;
|
||||
unsigned char drift_time;
|
||||
struct trackpoint_data {
|
||||
u8 variant_id;
|
||||
u8 firmware_id;
|
||||
|
||||
u8 sensitivity, speed, inertia, reach;
|
||||
u8 draghys, mindrag;
|
||||
u8 thresh, upthresh;
|
||||
u8 ztime, jenks;
|
||||
u8 drift_time;
|
||||
|
||||
/* toggles */
|
||||
unsigned char press_to_select;
|
||||
unsigned char skipback;
|
||||
unsigned char ext_dev;
|
||||
bool press_to_select;
|
||||
bool skipback;
|
||||
bool ext_dev;
|
||||
};
|
||||
|
||||
#ifdef CONFIG_MOUSE_PS2_TRACKPOINT
|
||||
|
@@ -316,11 +316,9 @@ static int vmmouse_enable(struct psmouse *psmouse)
|
||||
/*
|
||||
* Array of supported hypervisors.
|
||||
*/
|
||||
static const struct hypervisor_x86 *vmmouse_supported_hypervisors[] = {
|
||||
&x86_hyper_vmware,
|
||||
#ifdef CONFIG_KVM_GUEST
|
||||
&x86_hyper_kvm,
|
||||
#endif
|
||||
static enum x86_hypervisor_type vmmouse_supported_hypervisors[] = {
|
||||
X86_HYPER_VMWARE,
|
||||
X86_HYPER_KVM,
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -331,7 +329,7 @@ static bool vmmouse_check_hypervisor(void)
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(vmmouse_supported_hypervisors); i++)
|
||||
if (vmmouse_supported_hypervisors[i] == x86_hyper)
|
||||
if (vmmouse_supported_hypervisors[i] == x86_hyper_type)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
|
@@ -230,8 +230,10 @@ static irqreturn_t rmi_irq_fn(int irq, void *dev_id)
|
||||
rmi_dbg(RMI_DEBUG_CORE, &rmi_dev->dev,
|
||||
"Failed to process interrupt request: %d\n", ret);
|
||||
|
||||
if (count)
|
||||
if (count) {
|
||||
kfree(attn_data.data);
|
||||
attn_data.data = NULL;
|
||||
}
|
||||
|
||||
if (!kfifo_is_empty(&drvdata->attn_fifo))
|
||||
return rmi_irq_fn(irq, dev_id);
|
||||
|
@@ -570,14 +570,19 @@ static int rmi_f01_probe(struct rmi_function *fn)
|
||||
|
||||
dev_set_drvdata(&fn->dev, f01);
|
||||
|
||||
error = devm_device_add_group(&fn->rmi_dev->dev, &rmi_f01_attr_group);
|
||||
error = sysfs_create_group(&fn->rmi_dev->dev.kobj, &rmi_f01_attr_group);
|
||||
if (error)
|
||||
dev_warn(&fn->dev,
|
||||
"Failed to create attribute group: %d\n", error);
|
||||
dev_warn(&fn->dev, "Failed to create sysfs group: %d\n", error);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void rmi_f01_remove(struct rmi_function *fn)
|
||||
{
|
||||
/* Note that the bus device is used, not the F01 device */
|
||||
sysfs_remove_group(&fn->rmi_dev->dev.kobj, &rmi_f01_attr_group);
|
||||
}
|
||||
|
||||
static int rmi_f01_config(struct rmi_function *fn)
|
||||
{
|
||||
struct f01_data *f01 = dev_get_drvdata(&fn->dev);
|
||||
@@ -717,6 +722,7 @@ struct rmi_function_handler rmi_f01_handler = {
|
||||
},
|
||||
.func = 0x01,
|
||||
.probe = rmi_f01_probe,
|
||||
.remove = rmi_f01_remove,
|
||||
.config = rmi_f01_config,
|
||||
.attention = rmi_f01_attention,
|
||||
.suspend = rmi_f01_suspend,
|
||||
|
@@ -312,7 +312,7 @@ static int rmi_smb_probe(struct i2c_client *client,
|
||||
rmi_smb->xport.dev = &client->dev;
|
||||
rmi_smb->xport.pdata = *pdata;
|
||||
rmi_smb->xport.pdata.irq = client->irq;
|
||||
rmi_smb->xport.proto_name = "smb2";
|
||||
rmi_smb->xport.proto_name = "smb";
|
||||
rmi_smb->xport.ops = &rmi_smb_ops;
|
||||
|
||||
smbus_version = rmi_smb_get_version(rmi_smb);
|
||||
@@ -322,7 +322,7 @@ static int rmi_smb_probe(struct i2c_client *client,
|
||||
rmi_dbg(RMI_DEBUG_XPORT, &client->dev, "Smbus version is %d",
|
||||
smbus_version);
|
||||
|
||||
if (smbus_version != 2) {
|
||||
if (smbus_version != 2 && smbus_version != 3) {
|
||||
dev_err(&client->dev, "Unrecognized SMB version %d\n",
|
||||
smbus_version);
|
||||
return -ENODEV;
|
||||
|
@@ -126,7 +126,7 @@ static int pm860x_touch_dt_init(struct platform_device *pdev,
|
||||
int data, n, ret;
|
||||
if (!np)
|
||||
return -ENODEV;
|
||||
np = of_find_node_by_name(np, "touch");
|
||||
np = of_get_child_by_name(np, "touch");
|
||||
if (!np) {
|
||||
dev_err(&pdev->dev, "Can't find touch node\n");
|
||||
return -EINVAL;
|
||||
@@ -144,13 +144,13 @@ static int pm860x_touch_dt_init(struct platform_device *pdev,
|
||||
if (data) {
|
||||
ret = pm860x_reg_write(i2c, PM8607_GPADC_MISC1, data);
|
||||
if (ret < 0)
|
||||
return -EINVAL;
|
||||
goto err_put_node;
|
||||
}
|
||||
/* set tsi prebias time */
|
||||
if (!of_property_read_u32(np, "marvell,88pm860x-tsi-prebias", &data)) {
|
||||
ret = pm860x_reg_write(i2c, PM8607_TSI_PREBIAS, data);
|
||||
if (ret < 0)
|
||||
return -EINVAL;
|
||||
goto err_put_node;
|
||||
}
|
||||
/* set prebias & prechg time of pen detect */
|
||||
data = 0;
|
||||
@@ -161,10 +161,18 @@ static int pm860x_touch_dt_init(struct platform_device *pdev,
|
||||
if (data) {
|
||||
ret = pm860x_reg_write(i2c, PM8607_PD_PREBIAS, data);
|
||||
if (ret < 0)
|
||||
return -EINVAL;
|
||||
goto err_put_node;
|
||||
}
|
||||
of_property_read_u32(np, "marvell,88pm860x-resistor-X", res_x);
|
||||
|
||||
of_node_put(np);
|
||||
|
||||
return 0;
|
||||
|
||||
err_put_node:
|
||||
of_node_put(np);
|
||||
|
||||
return -EINVAL;
|
||||
}
|
||||
#else
|
||||
#define pm860x_touch_dt_init(x, y, z) (-1)
|
||||
|
@@ -759,7 +759,7 @@ config TOUCHSCREEN_WM831X
|
||||
|
||||
config TOUCHSCREEN_WM97XX
|
||||
tristate "Support for WM97xx AC97 touchscreen controllers"
|
||||
depends on AC97_BUS
|
||||
depends on AC97_BUS || AC97_BUS_NEW
|
||||
help
|
||||
Say Y here if you have a Wolfson Microelectronics WM97xx
|
||||
touchscreen connected to your system. Note that this option
|
||||
|
@@ -27,6 +27,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/input.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/irq.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/async.h>
|
||||
#include <linux/i2c.h>
|
||||
@@ -1260,10 +1261,13 @@ static int elants_i2c_probe(struct i2c_client *client,
|
||||
}
|
||||
|
||||
/*
|
||||
* Systems using device tree should set up interrupt via DTS,
|
||||
* the rest will use the default falling edge interrupts.
|
||||
* Platform code (ACPI, DTS) should normally set up interrupt
|
||||
* for us, but in case it did not let's fall back to using falling
|
||||
* edge to be compatible with older Chromebooks.
|
||||
*/
|
||||
irqflags = client->dev.of_node ? 0 : IRQF_TRIGGER_FALLING;
|
||||
irqflags = irq_get_trigger_type(client->irq);
|
||||
if (!irqflags)
|
||||
irqflags = IRQF_TRIGGER_FALLING;
|
||||
|
||||
error = devm_request_threaded_irq(&client->dev, client->irq,
|
||||
NULL, elants_i2c_irq,
|
||||
|
@@ -10,8 +10,7 @@
|
||||
#include <linux/of.h>
|
||||
#include <linux/firmware.h>
|
||||
#include <linux/delay.h>
|
||||
#include <linux/gpio.h>
|
||||
#include <linux/gpio/machine.h>
|
||||
#include <linux/gpio/consumer.h>
|
||||
#include <linux/i2c.h>
|
||||
#include <linux/acpi.h>
|
||||
#include <linux/interrupt.h>
|
||||
|
@@ -13,6 +13,7 @@
|
||||
#include <linux/input.h>
|
||||
#include <linux/input/mt.h>
|
||||
#include <linux/input/touchscreen.h>
|
||||
#include <linux/module.h>
|
||||
|
||||
static bool touchscreen_get_prop_u32(struct device *dev,
|
||||
const char *property,
|
||||
@@ -185,3 +186,6 @@ void touchscreen_report_pos(struct input_dev *input,
|
||||
input_report_abs(input, multitouch ? ABS_MT_POSITION_Y : ABS_Y, y);
|
||||
}
|
||||
EXPORT_SYMBOL(touchscreen_report_pos);
|
||||
|
||||
MODULE_LICENSE("GPL v2");
|
||||
MODULE_DESCRIPTION("Device-tree helpers functions for touchscreen devices");
|
||||
|
@@ -102,7 +102,7 @@ static inline bool get_down(unsigned long data0, unsigned long data1)
|
||||
!(data1 & S3C2410_ADCDAT0_UPDOWN));
|
||||
}
|
||||
|
||||
static void touch_timer_fire(unsigned long data)
|
||||
static void touch_timer_fire(struct timer_list *unused)
|
||||
{
|
||||
unsigned long data0;
|
||||
unsigned long data1;
|
||||
@@ -145,7 +145,7 @@ static void touch_timer_fire(unsigned long data)
|
||||
}
|
||||
}
|
||||
|
||||
static DEFINE_TIMER(touch_timer, touch_timer_fire, 0, 0);
|
||||
static DEFINE_TIMER(touch_timer, touch_timer_fire);
|
||||
|
||||
/**
|
||||
* stylus_irq - touchscreen stylus event interrupt
|
||||
|
@@ -104,7 +104,6 @@ static int tsc2007_read_raw(struct iio_dev *indio_dev,
|
||||
|
||||
static const struct iio_info tsc2007_iio_info = {
|
||||
.read_raw = tsc2007_read_raw,
|
||||
.driver_module = THIS_MODULE,
|
||||
};
|
||||
|
||||
int tsc2007_iio_configure(struct tsc2007 *ts)
|
||||
|
@@ -531,6 +531,7 @@ int tsc200x_probe(struct device *dev, int irq, const struct input_id *tsc_id,
|
||||
|
||||
input_set_drvdata(input_dev, ts);
|
||||
|
||||
__set_bit(INPUT_PROP_DIRECT, input_dev->propbit);
|
||||
input_set_capability(input_dev, EV_KEY, BTN_TOUCH);
|
||||
|
||||
input_set_abs_params(input_dev, ABS_X,
|
||||
|
@@ -44,6 +44,7 @@
|
||||
#include <linux/pm.h>
|
||||
#include <linux/interrupt.h>
|
||||
#include <linux/bitops.h>
|
||||
#include <linux/mfd/wm97xx.h>
|
||||
#include <linux/workqueue.h>
|
||||
#include <linux/wm97xx.h>
|
||||
#include <linux/uaccess.h>
|
||||
@@ -581,27 +582,85 @@ static void wm97xx_ts_input_close(struct input_dev *idev)
|
||||
wm->codec->acc_enable(wm, 0);
|
||||
}
|
||||
|
||||
static int wm97xx_probe(struct device *dev)
|
||||
static int wm97xx_register_touch(struct wm97xx *wm)
|
||||
{
|
||||
struct wm97xx *wm;
|
||||
struct wm97xx_pdata *pdata = dev_get_platdata(dev);
|
||||
int ret = 0, id = 0;
|
||||
struct wm97xx_pdata *pdata = dev_get_platdata(wm->dev);
|
||||
int ret;
|
||||
|
||||
wm = kzalloc(sizeof(struct wm97xx), GFP_KERNEL);
|
||||
if (!wm)
|
||||
wm->input_dev = devm_input_allocate_device(wm->dev);
|
||||
if (wm->input_dev == NULL)
|
||||
return -ENOMEM;
|
||||
mutex_init(&wm->codec_mutex);
|
||||
|
||||
wm->dev = dev;
|
||||
dev_set_drvdata(dev, wm);
|
||||
wm->ac97 = to_ac97_t(dev);
|
||||
/* set up touch configuration */
|
||||
wm->input_dev->name = "wm97xx touchscreen";
|
||||
wm->input_dev->phys = "wm97xx";
|
||||
wm->input_dev->open = wm97xx_ts_input_open;
|
||||
wm->input_dev->close = wm97xx_ts_input_close;
|
||||
|
||||
__set_bit(EV_ABS, wm->input_dev->evbit);
|
||||
__set_bit(EV_KEY, wm->input_dev->evbit);
|
||||
__set_bit(BTN_TOUCH, wm->input_dev->keybit);
|
||||
|
||||
input_set_abs_params(wm->input_dev, ABS_X, abs_x[0], abs_x[1],
|
||||
abs_x[2], 0);
|
||||
input_set_abs_params(wm->input_dev, ABS_Y, abs_y[0], abs_y[1],
|
||||
abs_y[2], 0);
|
||||
input_set_abs_params(wm->input_dev, ABS_PRESSURE, abs_p[0], abs_p[1],
|
||||
abs_p[2], 0);
|
||||
|
||||
input_set_drvdata(wm->input_dev, wm);
|
||||
wm->input_dev->dev.parent = wm->dev;
|
||||
|
||||
ret = input_register_device(wm->input_dev);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
/*
|
||||
* register our extended touch device (for machine specific
|
||||
* extensions)
|
||||
*/
|
||||
wm->touch_dev = platform_device_alloc("wm97xx-touch", -1);
|
||||
if (!wm->touch_dev) {
|
||||
ret = -ENOMEM;
|
||||
goto touch_err;
|
||||
}
|
||||
platform_set_drvdata(wm->touch_dev, wm);
|
||||
wm->touch_dev->dev.parent = wm->dev;
|
||||
wm->touch_dev->dev.platform_data = pdata;
|
||||
ret = platform_device_add(wm->touch_dev);
|
||||
if (ret < 0)
|
||||
goto touch_reg_err;
|
||||
|
||||
return 0;
|
||||
touch_reg_err:
|
||||
platform_device_put(wm->touch_dev);
|
||||
touch_err:
|
||||
input_unregister_device(wm->input_dev);
|
||||
wm->input_dev = NULL;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void wm97xx_unregister_touch(struct wm97xx *wm)
|
||||
{
|
||||
platform_device_unregister(wm->touch_dev);
|
||||
input_unregister_device(wm->input_dev);
|
||||
wm->input_dev = NULL;
|
||||
}
|
||||
|
||||
static int _wm97xx_probe(struct wm97xx *wm)
|
||||
{
|
||||
int id = 0;
|
||||
|
||||
mutex_init(&wm->codec_mutex);
|
||||
dev_set_drvdata(wm->dev, wm);
|
||||
|
||||
/* check that we have a supported codec */
|
||||
id = wm97xx_reg_read(wm, AC97_VENDOR_ID1);
|
||||
if (id != WM97XX_ID1) {
|
||||
dev_err(dev, "Device with vendor %04x is not a wm97xx\n", id);
|
||||
ret = -ENODEV;
|
||||
goto alloc_err;
|
||||
dev_err(wm->dev,
|
||||
"Device with vendor %04x is not a wm97xx\n", id);
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
wm->id = wm97xx_reg_read(wm, AC97_VENDOR_ID2);
|
||||
@@ -629,8 +688,7 @@ static int wm97xx_probe(struct device *dev)
|
||||
default:
|
||||
dev_err(wm->dev, "Support for wm97%02x not compiled in.\n",
|
||||
wm->id & 0xff);
|
||||
ret = -ENODEV;
|
||||
goto alloc_err;
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
/* set up physical characteristics */
|
||||
@@ -644,79 +702,58 @@ static int wm97xx_probe(struct device *dev)
|
||||
wm->gpio[4] = wm97xx_reg_read(wm, AC97_GPIO_STATUS);
|
||||
wm->gpio[5] = wm97xx_reg_read(wm, AC97_MISC_AFE);
|
||||
|
||||
wm->input_dev = input_allocate_device();
|
||||
if (wm->input_dev == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto alloc_err;
|
||||
}
|
||||
return wm97xx_register_touch(wm);
|
||||
}
|
||||
|
||||
/* set up touch configuration */
|
||||
wm->input_dev->name = "wm97xx touchscreen";
|
||||
wm->input_dev->phys = "wm97xx";
|
||||
wm->input_dev->open = wm97xx_ts_input_open;
|
||||
wm->input_dev->close = wm97xx_ts_input_close;
|
||||
static void wm97xx_remove_battery(struct wm97xx *wm)
|
||||
{
|
||||
platform_device_unregister(wm->battery_dev);
|
||||
}
|
||||
|
||||
__set_bit(EV_ABS, wm->input_dev->evbit);
|
||||
__set_bit(EV_KEY, wm->input_dev->evbit);
|
||||
__set_bit(BTN_TOUCH, wm->input_dev->keybit);
|
||||
static int wm97xx_add_battery(struct wm97xx *wm,
|
||||
struct wm97xx_batt_pdata *pdata)
|
||||
{
|
||||
int ret;
|
||||
|
||||
input_set_abs_params(wm->input_dev, ABS_X, abs_x[0], abs_x[1],
|
||||
abs_x[2], 0);
|
||||
input_set_abs_params(wm->input_dev, ABS_Y, abs_y[0], abs_y[1],
|
||||
abs_y[2], 0);
|
||||
input_set_abs_params(wm->input_dev, ABS_PRESSURE, abs_p[0], abs_p[1],
|
||||
abs_p[2], 0);
|
||||
|
||||
input_set_drvdata(wm->input_dev, wm);
|
||||
wm->input_dev->dev.parent = dev;
|
||||
|
||||
ret = input_register_device(wm->input_dev);
|
||||
if (ret < 0)
|
||||
goto dev_alloc_err;
|
||||
|
||||
/* register our battery device */
|
||||
wm->battery_dev = platform_device_alloc("wm97xx-battery", -1);
|
||||
if (!wm->battery_dev) {
|
||||
ret = -ENOMEM;
|
||||
goto batt_err;
|
||||
}
|
||||
platform_set_drvdata(wm->battery_dev, wm);
|
||||
wm->battery_dev->dev.parent = dev;
|
||||
wm->battery_dev->dev.platform_data = pdata ? pdata->batt_pdata : NULL;
|
||||
ret = platform_device_add(wm->battery_dev);
|
||||
if (ret < 0)
|
||||
goto batt_reg_err;
|
||||
if (!wm->battery_dev)
|
||||
return -ENOMEM;
|
||||
|
||||
/* register our extended touch device (for machine specific
|
||||
* extensions) */
|
||||
wm->touch_dev = platform_device_alloc("wm97xx-touch", -1);
|
||||
if (!wm->touch_dev) {
|
||||
ret = -ENOMEM;
|
||||
goto touch_err;
|
||||
}
|
||||
platform_set_drvdata(wm->touch_dev, wm);
|
||||
wm->touch_dev->dev.parent = dev;
|
||||
wm->touch_dev->dev.platform_data = pdata;
|
||||
ret = platform_device_add(wm->touch_dev);
|
||||
platform_set_drvdata(wm->battery_dev, wm);
|
||||
wm->battery_dev->dev.parent = wm->dev;
|
||||
wm->battery_dev->dev.platform_data = pdata;
|
||||
ret = platform_device_add(wm->battery_dev);
|
||||
if (ret)
|
||||
platform_device_put(wm->battery_dev);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wm97xx_probe(struct device *dev)
|
||||
{
|
||||
struct wm97xx *wm;
|
||||
int ret;
|
||||
struct wm97xx_pdata *pdata = dev_get_platdata(dev);
|
||||
|
||||
wm = devm_kzalloc(dev, sizeof(struct wm97xx), GFP_KERNEL);
|
||||
if (!wm)
|
||||
return -ENOMEM;
|
||||
|
||||
wm->dev = dev;
|
||||
wm->ac97 = to_ac97_t(dev);
|
||||
|
||||
ret = _wm97xx_probe(wm);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = wm97xx_add_battery(wm, pdata ? pdata->batt_pdata : NULL);
|
||||
if (ret < 0)
|
||||
goto touch_reg_err;
|
||||
goto batt_err;
|
||||
|
||||
return ret;
|
||||
|
||||
touch_reg_err:
|
||||
platform_device_put(wm->touch_dev);
|
||||
touch_err:
|
||||
platform_device_del(wm->battery_dev);
|
||||
batt_reg_err:
|
||||
platform_device_put(wm->battery_dev);
|
||||
batt_err:
|
||||
input_unregister_device(wm->input_dev);
|
||||
wm->input_dev = NULL;
|
||||
dev_alloc_err:
|
||||
input_free_device(wm->input_dev);
|
||||
alloc_err:
|
||||
kfree(wm);
|
||||
|
||||
batt_err:
|
||||
wm97xx_unregister_touch(wm);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -724,14 +761,45 @@ static int wm97xx_remove(struct device *dev)
|
||||
{
|
||||
struct wm97xx *wm = dev_get_drvdata(dev);
|
||||
|
||||
platform_device_unregister(wm->battery_dev);
|
||||
platform_device_unregister(wm->touch_dev);
|
||||
input_unregister_device(wm->input_dev);
|
||||
kfree(wm);
|
||||
wm97xx_remove_battery(wm);
|
||||
wm97xx_unregister_touch(wm);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int wm97xx_mfd_probe(struct platform_device *pdev)
|
||||
{
|
||||
struct wm97xx *wm;
|
||||
struct wm97xx_platform_data *mfd_pdata = dev_get_platdata(&pdev->dev);
|
||||
int ret;
|
||||
|
||||
wm = devm_kzalloc(&pdev->dev, sizeof(struct wm97xx), GFP_KERNEL);
|
||||
if (!wm)
|
||||
return -ENOMEM;
|
||||
|
||||
wm->dev = &pdev->dev;
|
||||
wm->ac97 = mfd_pdata->ac97;
|
||||
|
||||
ret = _wm97xx_probe(wm);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ret = wm97xx_add_battery(wm, mfd_pdata->batt_pdata);
|
||||
if (ret < 0)
|
||||
goto batt_err;
|
||||
|
||||
return ret;
|
||||
|
||||
batt_err:
|
||||
wm97xx_unregister_touch(wm);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int wm97xx_mfd_remove(struct platform_device *pdev)
|
||||
{
|
||||
return wm97xx_remove(&pdev->dev);
|
||||
}
|
||||
|
||||
static int __maybe_unused wm97xx_suspend(struct device *dev)
|
||||
{
|
||||
struct wm97xx *wm = dev_get_drvdata(dev);
|
||||
@@ -828,21 +896,41 @@ EXPORT_SYMBOL_GPL(wm97xx_unregister_mach_ops);
|
||||
|
||||
static struct device_driver wm97xx_driver = {
|
||||
.name = "wm97xx-ts",
|
||||
#ifdef CONFIG_AC97_BUS
|
||||
.bus = &ac97_bus_type,
|
||||
#endif
|
||||
.owner = THIS_MODULE,
|
||||
.probe = wm97xx_probe,
|
||||
.remove = wm97xx_remove,
|
||||
.pm = &wm97xx_pm_ops,
|
||||
};
|
||||
|
||||
static struct platform_driver wm97xx_mfd_driver = {
|
||||
.driver = {
|
||||
.name = "wm97xx-ts",
|
||||
.pm = &wm97xx_pm_ops,
|
||||
},
|
||||
.probe = wm97xx_mfd_probe,
|
||||
.remove = wm97xx_mfd_remove,
|
||||
};
|
||||
|
||||
static int __init wm97xx_init(void)
|
||||
{
|
||||
return driver_register(&wm97xx_driver);
|
||||
int ret;
|
||||
|
||||
ret = platform_driver_register(&wm97xx_mfd_driver);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (IS_BUILTIN(CONFIG_AC97_BUS))
|
||||
ret = driver_register(&wm97xx_driver);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void __exit wm97xx_exit(void)
|
||||
{
|
||||
driver_unregister(&wm97xx_driver);
|
||||
platform_driver_unregister(&wm97xx_mfd_driver);
|
||||
}
|
||||
|
||||
module_init(wm97xx_init);
|
||||
|
Reference in New Issue
Block a user