|
@@ -196,6 +196,8 @@ struct adxl34x {
|
|
struct axis_triple hwcal;
|
|
struct axis_triple hwcal;
|
|
struct axis_triple saved;
|
|
struct axis_triple saved;
|
|
char phys[32];
|
|
char phys[32];
|
|
|
|
+ unsigned orient2d_saved;
|
|
|
|
+ unsigned orient3d_saved;
|
|
bool disabled; /* P: mutex */
|
|
bool disabled; /* P: mutex */
|
|
bool opened; /* P: mutex */
|
|
bool opened; /* P: mutex */
|
|
bool fifo_delay;
|
|
bool fifo_delay;
|
|
@@ -296,7 +298,7 @@ static irqreturn_t adxl34x_irq(int irq, void *handle)
|
|
{
|
|
{
|
|
struct adxl34x *ac = handle;
|
|
struct adxl34x *ac = handle;
|
|
struct adxl34x_platform_data *pdata = &ac->pdata;
|
|
struct adxl34x_platform_data *pdata = &ac->pdata;
|
|
- int int_stat, tap_stat, samples;
|
|
|
|
|
|
+ int int_stat, tap_stat, samples, orient, orient_code;
|
|
|
|
|
|
/*
|
|
/*
|
|
* ACT_TAP_STATUS should be read before clearing the interrupt
|
|
* ACT_TAP_STATUS should be read before clearing the interrupt
|
|
@@ -332,6 +334,36 @@ static irqreturn_t adxl34x_irq(int irq, void *handle)
|
|
pdata->ev_code_act_inactivity, 0);
|
|
pdata->ev_code_act_inactivity, 0);
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ /*
|
|
|
|
+ * ORIENTATION SENSING ADXL346 only
|
|
|
|
+ */
|
|
|
|
+ if (pdata->orientation_enable) {
|
|
|
|
+ orient = AC_READ(ac, ORIENT);
|
|
|
|
+ if ((pdata->orientation_enable & ADXL_EN_ORIENTATION_2D) &&
|
|
|
|
+ (orient & ADXL346_2D_VALID)) {
|
|
|
|
+
|
|
|
|
+ orient_code = ADXL346_2D_ORIENT(orient);
|
|
|
|
+ /* Report orientation only when it changes */
|
|
|
|
+ if (ac->orient2d_saved != orient_code) {
|
|
|
|
+ ac->orient2d_saved = orient_code;
|
|
|
|
+ adxl34x_report_key_single(ac->input,
|
|
|
|
+ pdata->ev_codes_orient_2d[orient_code]);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if ((pdata->orientation_enable & ADXL_EN_ORIENTATION_3D) &&
|
|
|
|
+ (orient & ADXL346_3D_VALID)) {
|
|
|
|
+
|
|
|
|
+ orient_code = ADXL346_3D_ORIENT(orient) - 1;
|
|
|
|
+ /* Report orientation only when it changes */
|
|
|
|
+ if (ac->orient3d_saved != orient_code) {
|
|
|
|
+ ac->orient3d_saved = orient_code;
|
|
|
|
+ adxl34x_report_key_single(ac->input,
|
|
|
|
+ pdata->ev_codes_orient_3d[orient_code]);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
if (int_stat & (DATA_READY | WATERMARK)) {
|
|
if (int_stat & (DATA_READY | WATERMARK)) {
|
|
|
|
|
|
if (pdata->fifo_mode)
|
|
if (pdata->fifo_mode)
|
|
@@ -641,7 +673,7 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq,
|
|
struct adxl34x *ac;
|
|
struct adxl34x *ac;
|
|
struct input_dev *input_dev;
|
|
struct input_dev *input_dev;
|
|
const struct adxl34x_platform_data *pdata;
|
|
const struct adxl34x_platform_data *pdata;
|
|
- int err, range;
|
|
|
|
|
|
+ int err, range, i;
|
|
unsigned char revid;
|
|
unsigned char revid;
|
|
|
|
|
|
if (!irq) {
|
|
if (!irq) {
|
|
@@ -797,12 +829,34 @@ struct adxl34x *adxl34x_probe(struct device *dev, int irq,
|
|
AC_WRITE(ac, FIFO_CTL, FIFO_MODE(pdata->fifo_mode) |
|
|
AC_WRITE(ac, FIFO_CTL, FIFO_MODE(pdata->fifo_mode) |
|
|
SAMPLES(pdata->watermark));
|
|
SAMPLES(pdata->watermark));
|
|
|
|
|
|
- if (pdata->use_int2)
|
|
|
|
|
|
+ if (pdata->use_int2) {
|
|
/* Map all INTs to INT2 */
|
|
/* Map all INTs to INT2 */
|
|
AC_WRITE(ac, INT_MAP, ac->int_mask | OVERRUN);
|
|
AC_WRITE(ac, INT_MAP, ac->int_mask | OVERRUN);
|
|
- else
|
|
|
|
|
|
+ } else {
|
|
/* Map all INTs to INT1 */
|
|
/* Map all INTs to INT1 */
|
|
AC_WRITE(ac, INT_MAP, 0);
|
|
AC_WRITE(ac, INT_MAP, 0);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ if (ac->model == 346 && ac->pdata.orientation_enable) {
|
|
|
|
+ AC_WRITE(ac, ORIENT_CONF,
|
|
|
|
+ ORIENT_DEADZONE(ac->pdata.deadzone_angle) |
|
|
|
|
+ ORIENT_DIVISOR(ac->pdata.divisor_length));
|
|
|
|
+
|
|
|
|
+ ac->orient2d_saved = 1234;
|
|
|
|
+ ac->orient3d_saved = 1234;
|
|
|
|
+
|
|
|
|
+ if (pdata->orientation_enable & ADXL_EN_ORIENTATION_3D)
|
|
|
|
+ for (i = 0; i < ARRAY_SIZE(pdata->ev_codes_orient_3d); i++)
|
|
|
|
+ __set_bit(pdata->ev_codes_orient_3d[i],
|
|
|
|
+ input_dev->keybit);
|
|
|
|
+
|
|
|
|
+ if (pdata->orientation_enable & ADXL_EN_ORIENTATION_2D)
|
|
|
|
+ for (i = 0; i < ARRAY_SIZE(pdata->ev_codes_orient_2d); i++)
|
|
|
|
+ __set_bit(pdata->ev_codes_orient_2d[i],
|
|
|
|
+ input_dev->keybit);
|
|
|
|
+ } else {
|
|
|
|
+ ac->pdata.orientation_enable = 0;
|
|
|
|
+ }
|
|
|
|
|
|
AC_WRITE(ac, INT_ENABLE, ac->int_mask | OVERRUN);
|
|
AC_WRITE(ac, INT_ENABLE, ac->int_mask | OVERRUN);
|
|
|
|
|