diff options
author | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-05-26 00:41:21 +0100 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2011-05-26 00:41:21 +0100 |
commit | ae1d3b974e091b5fc9008bd41bcbdaac68110b62 (patch) | |
tree | 82e50a66925ced79f59ed4504f6e073ef55edee3 /drivers/input/misc | |
parent | 586893ebc42943008010b4c210cfc9167df615e5 (diff) | |
parent | 7a2207a0e1142a9b214b323e43ab2ecc592e5b0e (diff) | |
download | talos-op-linux-ae1d3b974e091b5fc9008bd41bcbdaac68110b62.tar.gz talos-op-linux-ae1d3b974e091b5fc9008bd41bcbdaac68110b62.zip |
Merge branch 'for-rmk' of git://github.com/at91linux/linux-2.6-at91 into devel-stable
Diffstat (limited to 'drivers/input/misc')
-rw-r--r-- | drivers/input/misc/ad714x.c | 129 | ||||
-rw-r--r-- | drivers/input/misc/ati_remote2.c | 9 | ||||
-rw-r--r-- | drivers/input/misc/rotary_encoder.c | 119 | ||||
-rw-r--r-- | drivers/input/misc/twl4030-pwrbutton.c | 2 |
4 files changed, 124 insertions, 135 deletions
diff --git a/drivers/input/misc/ad714x.c b/drivers/input/misc/ad714x.c index c431d09e401a..c3a62c42cd28 100644 --- a/drivers/input/misc/ad714x.c +++ b/drivers/input/misc/ad714x.c @@ -79,13 +79,7 @@ struct ad714x_slider_drv { struct ad714x_wheel_drv { int abs_pos; int flt_pos; - int pre_mean_value; int pre_highest_stage; - int pre_mean_value_no_offset; - int mean_value; - int mean_value_no_offset; - int pos_offset; - int pos_ratio; int highest_stage; enum ad714x_device_state state; struct input_dev *input; @@ -158,10 +152,10 @@ static void ad714x_use_com_int(struct ad714x_chip *ad714x, unsigned short data; unsigned short mask; - mask = ((1 << (end_stage + 1)) - 1) - (1 << start_stage); + mask = ((1 << (end_stage + 1)) - 1) - ((1 << start_stage) - 1); ad714x->read(ad714x->dev, STG_COM_INT_EN_REG, &data); - data |= 1 << start_stage; + data |= 1 << end_stage; ad714x->write(ad714x->dev, STG_COM_INT_EN_REG, data); ad714x->read(ad714x->dev, STG_HIGH_INT_EN_REG, &data); @@ -175,10 +169,10 @@ static void ad714x_use_thr_int(struct ad714x_chip *ad714x, unsigned short data; unsigned short mask; - mask = ((1 << (end_stage + 1)) - 1) - (1 << start_stage); + mask = ((1 << (end_stage + 1)) - 1) - ((1 << start_stage) - 1); ad714x->read(ad714x->dev, STG_COM_INT_EN_REG, &data); - data &= ~(1 << start_stage); + data &= ~(1 << end_stage); ad714x->write(ad714x->dev, STG_COM_INT_EN_REG, data); ad714x->read(ad714x->dev, STG_HIGH_INT_EN_REG, &data); @@ -404,7 +398,6 @@ static void ad714x_slider_state_machine(struct ad714x_chip *ad714x, int idx) ad714x_slider_cal_highest_stage(ad714x, idx); ad714x_slider_cal_abs_pos(ad714x, idx); ad714x_slider_cal_flt_pos(ad714x, idx); - input_report_abs(sw->input, ABS_X, sw->flt_pos); input_report_key(sw->input, BTN_TOUCH, 1); } else { @@ -468,104 +461,41 @@ static void ad714x_wheel_cal_sensor_val(struct ad714x_chip *ad714x, int idx) /* * When the scroll wheel is activated, we compute the absolute position based * on the sensor values. To calculate the position, we first determine the - * sensor that has the greatest response among the 8 sensors that constitutes - * the scrollwheel. Then we determined the 2 sensors on either sides of the + * sensor that has the greatest response among the sensors that constitutes + * the scrollwheel. Then we determined the sensors on either sides of the * sensor with the highest response and we apply weights to these sensors. The - * result of this computation gives us the mean value which defined by the - * following formula: - * For i= second_before_highest_stage to i= second_after_highest_stage - * v += Sensor response(i)*WEIGHT*(i+3) - * w += Sensor response(i) - * Mean_Value=v/w - * pos_on_scrollwheel = (Mean_Value - position_offset) / position_ratio + * result of this computation gives us the mean value. */ -#define WEIGHT_FACTOR 30 -/* This constant prevents the "PositionOffset" from reaching a big value */ -#define OFFSET_POSITION_CLAMP 120 static void ad714x_wheel_cal_abs_pos(struct ad714x_chip *ad714x, int idx) { struct ad714x_wheel_plat *hw = &ad714x->hw->wheel[idx]; struct ad714x_wheel_drv *sw = &ad714x->sw->wheel[idx]; int stage_num = hw->end_stage - hw->start_stage + 1; - int second_before, first_before, highest, first_after, second_after; + int first_before, highest, first_after; int a_param, b_param; - /* Calculate Mean value */ - - second_before = (sw->highest_stage + stage_num - 2) % stage_num; first_before = (sw->highest_stage + stage_num - 1) % stage_num; highest = sw->highest_stage; first_after = (sw->highest_stage + stage_num + 1) % stage_num; - second_after = (sw->highest_stage + stage_num + 2) % stage_num; - - if (((sw->highest_stage - hw->start_stage) > 1) && - ((hw->end_stage - sw->highest_stage) > 1)) { - a_param = ad714x->sensor_val[second_before] * - (second_before - hw->start_stage + 3) + - ad714x->sensor_val[first_before] * - (second_before - hw->start_stage + 3) + - ad714x->sensor_val[highest] * - (second_before - hw->start_stage + 3) + - ad714x->sensor_val[first_after] * - (first_after - hw->start_stage + 3) + - ad714x->sensor_val[second_after] * - (second_after - hw->start_stage + 3); - } else { - a_param = ad714x->sensor_val[second_before] * - (second_before - hw->start_stage + 1) + - ad714x->sensor_val[first_before] * - (second_before - hw->start_stage + 2) + - ad714x->sensor_val[highest] * - (second_before - hw->start_stage + 3) + - ad714x->sensor_val[first_after] * - (first_after - hw->start_stage + 4) + - ad714x->sensor_val[second_after] * - (second_after - hw->start_stage + 5); - } - a_param *= WEIGHT_FACTOR; - b_param = ad714x->sensor_val[second_before] + + a_param = ad714x->sensor_val[highest] * + (highest - hw->start_stage) + + ad714x->sensor_val[first_before] * + (highest - hw->start_stage - 1) + + ad714x->sensor_val[first_after] * + (highest - hw->start_stage + 1); + b_param = ad714x->sensor_val[highest] + ad714x->sensor_val[first_before] + - ad714x->sensor_val[highest] + - ad714x->sensor_val[first_after] + - ad714x->sensor_val[second_after]; - - sw->pre_mean_value = sw->mean_value; - sw->mean_value = a_param / b_param; - - /* Calculate the offset */ - - if ((sw->pre_highest_stage == hw->end_stage) && - (sw->highest_stage == hw->start_stage)) - sw->pos_offset = sw->mean_value; - else if ((sw->pre_highest_stage == hw->start_stage) && - (sw->highest_stage == hw->end_stage)) - sw->pos_offset = sw->pre_mean_value; - - if (sw->pos_offset > OFFSET_POSITION_CLAMP) - sw->pos_offset = OFFSET_POSITION_CLAMP; - - /* Calculate the mean value without the offset */ - - sw->pre_mean_value_no_offset = sw->mean_value_no_offset; - sw->mean_value_no_offset = sw->mean_value - sw->pos_offset; - if (sw->mean_value_no_offset < 0) - sw->mean_value_no_offset = 0; - - /* Calculate ratio to scale down to NUMBER_OF_WANTED_POSITIONS */ - - if ((sw->pre_highest_stage == hw->end_stage) && - (sw->highest_stage == hw->start_stage)) - sw->pos_ratio = (sw->pre_mean_value_no_offset * 100) / - hw->max_coord; - else if ((sw->pre_highest_stage == hw->start_stage) && - (sw->highest_stage == hw->end_stage)) - sw->pos_ratio = (sw->mean_value_no_offset * 100) / - hw->max_coord; - sw->abs_pos = (sw->mean_value_no_offset * 100) / sw->pos_ratio; + ad714x->sensor_val[first_after]; + + sw->abs_pos = ((hw->max_coord / (hw->end_stage - hw->start_stage)) * + a_param) / b_param; + if (sw->abs_pos > hw->max_coord) sw->abs_pos = hw->max_coord; + else if (sw->abs_pos < 0) + sw->abs_pos = 0; } static void ad714x_wheel_cal_flt_pos(struct ad714x_chip *ad714x, int idx) @@ -639,9 +569,8 @@ static void ad714x_wheel_state_machine(struct ad714x_chip *ad714x, int idx) ad714x_wheel_cal_highest_stage(ad714x, idx); ad714x_wheel_cal_abs_pos(ad714x, idx); ad714x_wheel_cal_flt_pos(ad714x, idx); - input_report_abs(sw->input, ABS_WHEEL, - sw->abs_pos); + sw->flt_pos); input_report_key(sw->input, BTN_TOUCH, 1); } else { /* When the user lifts off the sensor, configure @@ -1149,6 +1078,8 @@ struct ad714x_chip *ad714x_probe(struct device *dev, u16 bus_type, int irq, input[alloc_idx]->id.bustype = bus_type; input[alloc_idx]->id.product = ad714x->product; input[alloc_idx]->id.version = ad714x->version; + input[alloc_idx]->name = "ad714x_captouch_slider"; + input[alloc_idx]->dev.parent = dev; error = input_register_device(input[alloc_idx]); if (error) @@ -1179,6 +1110,8 @@ struct ad714x_chip *ad714x_probe(struct device *dev, u16 bus_type, int irq, input[alloc_idx]->id.bustype = bus_type; input[alloc_idx]->id.product = ad714x->product; input[alloc_idx]->id.version = ad714x->version; + input[alloc_idx]->name = "ad714x_captouch_wheel"; + input[alloc_idx]->dev.parent = dev; error = input_register_device(input[alloc_idx]); if (error) @@ -1212,6 +1145,8 @@ struct ad714x_chip *ad714x_probe(struct device *dev, u16 bus_type, int irq, input[alloc_idx]->id.bustype = bus_type; input[alloc_idx]->id.product = ad714x->product; input[alloc_idx]->id.version = ad714x->version; + input[alloc_idx]->name = "ad714x_captouch_pad"; + input[alloc_idx]->dev.parent = dev; error = input_register_device(input[alloc_idx]); if (error) @@ -1240,6 +1175,8 @@ struct ad714x_chip *ad714x_probe(struct device *dev, u16 bus_type, int irq, input[alloc_idx]->id.bustype = bus_type; input[alloc_idx]->id.product = ad714x->product; input[alloc_idx]->id.version = ad714x->version; + input[alloc_idx]->name = "ad714x_captouch_button"; + input[alloc_idx]->dev.parent = dev; error = input_register_device(input[alloc_idx]); if (error) @@ -1249,7 +1186,9 @@ struct ad714x_chip *ad714x_probe(struct device *dev, u16 bus_type, int irq, } error = request_threaded_irq(ad714x->irq, NULL, ad714x_interrupt_thread, - IRQF_TRIGGER_FALLING, "ad714x_captouch", ad714x); + plat_data->irqflags ? + plat_data->irqflags : IRQF_TRIGGER_FALLING, + "ad714x_captouch", ad714x); if (error) { dev_err(dev, "can't allocate irq %d\n", ad714x->irq); goto err_unreg_dev; diff --git a/drivers/input/misc/ati_remote2.c b/drivers/input/misc/ati_remote2.c index 9ccdb82d869a..1de58e8a1b71 100644 --- a/drivers/input/misc/ati_remote2.c +++ b/drivers/input/misc/ati_remote2.c @@ -737,14 +737,17 @@ static ssize_t ati_remote2_store_channel_mask(struct device *dev, mutex_lock(&ati_remote2_mutex); - if (mask != ar2->channel_mask && !ati_remote2_setup(ar2, mask)) - ar2->channel_mask = mask; + if (mask != ar2->channel_mask) { + r = ati_remote2_setup(ar2, mask); + if (!r) + ar2->channel_mask = mask; + } mutex_unlock(&ati_remote2_mutex); usb_autopm_put_interface(ar2->intf[0]); - return count; + return r ? r : count; } static ssize_t ati_remote2_show_mode_mask(struct device *dev, diff --git a/drivers/input/misc/rotary_encoder.c b/drivers/input/misc/rotary_encoder.c index 7e64d01da2be..2c8b84dd9dac 100644 --- a/drivers/input/misc/rotary_encoder.c +++ b/drivers/input/misc/rotary_encoder.c @@ -2,6 +2,7 @@ * rotary_encoder.c * * (c) 2009 Daniel Mack <daniel@caiaq.de> + * Copyright (C) 2011 Johan Hovold <jhovold@gmail.com> * * state machine code inspired by code from Tim Ruetz * @@ -38,52 +39,66 @@ struct rotary_encoder { bool armed; unsigned char dir; /* 0 - clockwise, 1 - CCW */ + + char last_stable; }; -static irqreturn_t rotary_encoder_irq(int irq, void *dev_id) +static int rotary_encoder_get_state(struct rotary_encoder_platform_data *pdata) { - struct rotary_encoder *encoder = dev_id; - struct rotary_encoder_platform_data *pdata = encoder->pdata; int a = !!gpio_get_value(pdata->gpio_a); int b = !!gpio_get_value(pdata->gpio_b); - int state; a ^= pdata->inverted_a; b ^= pdata->inverted_b; - state = (a << 1) | b; - switch (state) { + return ((a << 1) | b); +} - case 0x0: - if (!encoder->armed) - break; +static void rotary_encoder_report_event(struct rotary_encoder *encoder) +{ + struct rotary_encoder_platform_data *pdata = encoder->pdata; - if (pdata->relative_axis) { - input_report_rel(encoder->input, pdata->axis, - encoder->dir ? -1 : 1); - } else { - unsigned int pos = encoder->pos; - - if (encoder->dir) { - /* turning counter-clockwise */ - if (pdata->rollover) - pos += pdata->steps; - if (pos) - pos--; - } else { - /* turning clockwise */ - if (pdata->rollover || pos < pdata->steps) - pos++; - } + if (pdata->relative_axis) { + input_report_rel(encoder->input, + pdata->axis, encoder->dir ? -1 : 1); + } else { + unsigned int pos = encoder->pos; + + if (encoder->dir) { + /* turning counter-clockwise */ if (pdata->rollover) - pos %= pdata->steps; - encoder->pos = pos; - input_report_abs(encoder->input, pdata->axis, - encoder->pos); + pos += pdata->steps; + if (pos) + pos--; + } else { + /* turning clockwise */ + if (pdata->rollover || pos < pdata->steps) + pos++; } - input_sync(encoder->input); - encoder->armed = false; + if (pdata->rollover) + pos %= pdata->steps; + + encoder->pos = pos; + input_report_abs(encoder->input, pdata->axis, encoder->pos); + } + + input_sync(encoder->input); +} + +static irqreturn_t rotary_encoder_irq(int irq, void *dev_id) +{ + struct rotary_encoder *encoder = dev_id; + int state; + + state = rotary_encoder_get_state(encoder->pdata); + + switch (state) { + case 0x0: + if (encoder->armed) { + rotary_encoder_report_event(encoder); + encoder->armed = false; + } break; case 0x1: @@ -100,11 +115,37 @@ static irqreturn_t rotary_encoder_irq(int irq, void *dev_id) return IRQ_HANDLED; } +static irqreturn_t rotary_encoder_half_period_irq(int irq, void *dev_id) +{ + struct rotary_encoder *encoder = dev_id; + int state; + + state = rotary_encoder_get_state(encoder->pdata); + + switch (state) { + case 0x00: + case 0x03: + if (state != encoder->last_stable) { + rotary_encoder_report_event(encoder); + encoder->last_stable = state; + } + break; + + case 0x01: + case 0x02: + encoder->dir = (encoder->last_stable + state) & 0x01; + break; + } + + return IRQ_HANDLED; +} + static int __devinit rotary_encoder_probe(struct platform_device *pdev) { struct rotary_encoder_platform_data *pdata = pdev->dev.platform_data; struct rotary_encoder *encoder; struct input_dev *input; + irq_handler_t handler; int err; if (!pdata) { @@ -175,7 +216,14 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev) } /* request the IRQs */ - err = request_irq(encoder->irq_a, &rotary_encoder_irq, + if (pdata->half_period) { + handler = &rotary_encoder_half_period_irq; + encoder->last_stable = rotary_encoder_get_state(pdata); + } else { + handler = &rotary_encoder_irq; + } + + err = request_irq(encoder->irq_a, handler, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, DRV_NAME, encoder); if (err) { @@ -184,7 +232,7 @@ static int __devinit rotary_encoder_probe(struct platform_device *pdev) goto exit_free_gpio_b; } - err = request_irq(encoder->irq_b, &rotary_encoder_irq, + err = request_irq(encoder->irq_b, handler, IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING, DRV_NAME, encoder); if (err) { @@ -252,6 +300,5 @@ module_exit(rotary_encoder_exit); MODULE_ALIAS("platform:" DRV_NAME); MODULE_DESCRIPTION("GPIO rotary encoder driver"); -MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>"); +MODULE_AUTHOR("Daniel Mack <daniel@caiaq.de>, Johan Hovold"); MODULE_LICENSE("GPL v2"); - diff --git a/drivers/input/misc/twl4030-pwrbutton.c b/drivers/input/misc/twl4030-pwrbutton.c index f16972bddca4..38e4b507b94c 100644 --- a/drivers/input/misc/twl4030-pwrbutton.c +++ b/drivers/input/misc/twl4030-pwrbutton.c @@ -89,7 +89,7 @@ static int __init twl4030_pwrbutton_probe(struct platform_device *pdev) return 0; free_irq: - free_irq(irq, NULL); + free_irq(irq, pwr); free_input_dev: input_free_device(pwr); return err; |