aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hwmon/hp_accel.c30
-rw-r--r--drivers/hwmon/lis3lv02d.c24
-rw-r--r--drivers/hwmon/lis3lv02d.h11
-rw-r--r--drivers/hwmon/lis3lv02d_i2c.c5
-rw-r--r--drivers/hwmon/lis3lv02d_spi.c3
5 files changed, 52 insertions, 21 deletions
diff --git a/drivers/hwmon/hp_accel.c b/drivers/hwmon/hp_accel.c
index c5cd3db78c94..a56a78412fcb 100644
--- a/drivers/hwmon/hp_accel.c
+++ b/drivers/hwmon/hp_accel.c
@@ -146,7 +146,7 @@ int lis3lv02d_acpi_write(struct lis3lv02d *lis3, int reg, u8 val)
146 146
147static int lis3lv02d_dmi_matched(const struct dmi_system_id *dmi) 147static int lis3lv02d_dmi_matched(const struct dmi_system_id *dmi)
148{ 148{
149 lis3_dev.ac = *((struct axis_conversion *)dmi->driver_data); 149 lis3_dev.ac = *((union axis_conversion *)dmi->driver_data);
150 printk(KERN_INFO DRIVER_NAME ": hardware type %s found.\n", dmi->ident); 150 printk(KERN_INFO DRIVER_NAME ": hardware type %s found.\n", dmi->ident);
151 151
152 return 1; 152 return 1;
@@ -154,16 +154,19 @@ static int lis3lv02d_dmi_matched(const struct dmi_system_id *dmi)
154 154
155/* Represents, for each axis seen by userspace, the corresponding hw axis (+1). 155/* Represents, for each axis seen by userspace, the corresponding hw axis (+1).
156 * If the value is negative, the opposite of the hw value is used. */ 156 * If the value is negative, the opposite of the hw value is used. */
157static struct axis_conversion lis3lv02d_axis_normal = {1, 2, 3}; 157#define DEFINE_CONV(name, x, y, z) \
158static struct axis_conversion lis3lv02d_axis_y_inverted = {1, -2, 3}; 158 static union axis_conversion lis3lv02d_axis_##name = \
159static struct axis_conversion lis3lv02d_axis_x_inverted = {-1, 2, 3}; 159 { .as_array = { x, y, z } }
160static struct axis_conversion lis3lv02d_axis_z_inverted = {1, 2, -3}; 160DEFINE_CONV(normal, 1, 2, 3);
161static struct axis_conversion lis3lv02d_axis_xy_swap = {2, 1, 3}; 161DEFINE_CONV(y_inverted, 1, -2, 3);
162static struct axis_conversion lis3lv02d_axis_xy_rotated_left = {-2, 1, 3}; 162DEFINE_CONV(x_inverted, -1, 2, 3);
163static struct axis_conversion lis3lv02d_axis_xy_rotated_left_usd = {-2, 1, -3}; 163DEFINE_CONV(z_inverted, 1, 2, -3);
164static struct axis_conversion lis3lv02d_axis_xy_swap_inverted = {-2, -1, 3}; 164DEFINE_CONV(xy_swap, 2, 1, 3);
165static struct axis_conversion lis3lv02d_axis_xy_rotated_right = {2, -1, 3}; 165DEFINE_CONV(xy_rotated_left, -2, 1, 3);
166static struct axis_conversion lis3lv02d_axis_xy_swap_yz_inverted = {2, -1, -3}; 166DEFINE_CONV(xy_rotated_left_usd, -2, 1, -3);
167DEFINE_CONV(xy_swap_inverted, -2, -1, 3);
168DEFINE_CONV(xy_rotated_right, 2, -1, 3);
169DEFINE_CONV(xy_swap_yz_inverted, 2, -1, -3);
167 170
168#define AXIS_DMI_MATCH(_ident, _name, _axis) { \ 171#define AXIS_DMI_MATCH(_ident, _name, _axis) { \
169 .ident = _ident, \ 172 .ident = _ident, \
@@ -299,7 +302,10 @@ static int lis3lv02d_add(struct acpi_device *device)
299 lis3lv02d_enum_resources(device); 302 lis3lv02d_enum_resources(device);
300 303
301 /* If possible use a "standard" axes order */ 304 /* If possible use a "standard" axes order */
302 if (dmi_check_system(lis3lv02d_dmi_ids) == 0) { 305 if (lis3_dev.ac.x && lis3_dev.ac.y && lis3_dev.ac.z) {
306 printk(KERN_INFO DRIVER_NAME ": Using custom axes %d,%d,%d\n",
307 lis3_dev.ac.x, lis3_dev.ac.y, lis3_dev.ac.z);
308 } else if (dmi_check_system(lis3lv02d_dmi_ids) == 0) {
303 printk(KERN_INFO DRIVER_NAME ": laptop model unknown, " 309 printk(KERN_INFO DRIVER_NAME ": laptop model unknown, "
304 "using default axes configuration\n"); 310 "using default axes configuration\n");
305 lis3_dev.ac = lis3lv02d_axis_normal; 311 lis3_dev.ac = lis3lv02d_axis_normal;
diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index ef7510d83603..25f385010953 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -75,6 +75,30 @@ struct lis3lv02d lis3_dev = {
75 75
76EXPORT_SYMBOL_GPL(lis3_dev); 76EXPORT_SYMBOL_GPL(lis3_dev);
77 77
78/* just like param_set_int() but does sanity-check so that it won't point
79 * over the axis array size
80 */
81static int param_set_axis(const char *val, const struct kernel_param *kp)
82{
83 int ret = param_set_int(val, kp);
84 if (!ret) {
85 int val = *(int *)kp->arg;
86 if (val < 0)
87 val = -val;
88 if (!val || val > 3)
89 return -EINVAL;
90 }
91 return ret;
92}
93
94static struct kernel_param_ops param_ops_axis = {
95 .set = param_set_axis,
96 .get = param_get_int,
97};
98
99module_param_array_named(axes, lis3_dev.ac.as_array, axis, NULL, 0644);
100MODULE_PARM_DESC(axes, "Axis-mapping for x,y,z directions");
101
78static s16 lis3lv02d_read_8(struct lis3lv02d *lis3, int reg) 102static s16 lis3lv02d_read_8(struct lis3lv02d *lis3, int reg)
79{ 103{
80 s8 lo; 104 s8 lo;
diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
index 62c6652eb9d5..eb5db584eb0e 100644
--- a/drivers/hwmon/lis3lv02d.h
+++ b/drivers/hwmon/lis3lv02d.h
@@ -223,10 +223,11 @@ enum lis3lv02d_click_src_8b {
223 CLICK_IA = 0x40, 223 CLICK_IA = 0x40,
224}; 224};
225 225
226struct axis_conversion { 226union axis_conversion {
227 s8 x; 227 struct {
228 s8 y; 228 int x, y, z;
229 s8 z; 229 };
230 int as_array[3];
230}; 231};
231 232
232struct lis3lv02d { 233struct lis3lv02d {
@@ -249,7 +250,7 @@ struct lis3lv02d {
249 struct input_polled_dev *idev; /* input device */ 250 struct input_polled_dev *idev; /* input device */
250 struct platform_device *pdev; /* platform device */ 251 struct platform_device *pdev; /* platform device */
251 atomic_t count; /* interrupt count after last read */ 252 atomic_t count; /* interrupt count after last read */
252 struct axis_conversion ac; /* hw -> logical axis */ 253 union axis_conversion ac; /* hw -> logical axis */
253 int mapped_btns[3]; 254 int mapped_btns[3];
254 255
255 u32 irq; /* IRQ number */ 256 u32 irq; /* IRQ number */
diff --git a/drivers/hwmon/lis3lv02d_i2c.c b/drivers/hwmon/lis3lv02d_i2c.c
index 8e5933b72d19..c6f3f3411276 100644
--- a/drivers/hwmon/lis3lv02d_i2c.c
+++ b/drivers/hwmon/lis3lv02d_i2c.c
@@ -61,9 +61,8 @@ static int lis3_i2c_init(struct lis3lv02d *lis3)
61} 61}
62 62
63/* Default axis mapping but it can be overwritten by platform data */ 63/* Default axis mapping but it can be overwritten by platform data */
64static struct axis_conversion lis3lv02d_axis_map = { LIS3_DEV_X, 64static union axis_conversion lis3lv02d_axis_map =
65 LIS3_DEV_Y, 65 { .as_array = { LIS3_DEV_X, LIS3_DEV_Y, LIS3_DEV_Z } };
66 LIS3_DEV_Z };
67 66
68static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client, 67static int __devinit lis3lv02d_i2c_probe(struct i2c_client *client,
69 const struct i2c_device_id *id) 68 const struct i2c_device_id *id)
diff --git a/drivers/hwmon/lis3lv02d_spi.c b/drivers/hwmon/lis3lv02d_spi.c
index b9be5e3a22b3..955544b1c71e 100644
--- a/drivers/hwmon/lis3lv02d_spi.c
+++ b/drivers/hwmon/lis3lv02d_spi.c
@@ -54,7 +54,8 @@ static int lis3_spi_init(struct lis3lv02d *lis3)
54 return lis3->write(lis3, CTRL_REG1, reg); 54 return lis3->write(lis3, CTRL_REG1, reg);
55} 55}
56 56
57static struct axis_conversion lis3lv02d_axis_normal = { 1, 2, 3 }; 57static union axis_conversion lis3lv02d_axis_normal =
58 { .as_array = { 1, 2, 3 } };
58 59
59static int __devinit lis302dl_spi_probe(struct spi_device *spi) 60static int __devinit lis302dl_spi_probe(struct spi_device *spi)
60{ 61{