summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--drivers/misc/m4sensorhub_als.c70
-rw-r--r--drivers/misc/m4sensorhub_fusion.c71
-rw-r--r--drivers/misc/m4sensorhub_heartrate.c74
-rw-r--r--drivers/misc/m4sensorhub_mpu9150.c313
-rw-r--r--drivers/misc/m4sensorhub_pedometer.c121
5 files changed, 196 insertions, 453 deletions
diff --git a/drivers/misc/m4sensorhub_als.c b/drivers/misc/m4sensorhub_als.c
index b5f90fd72a3..84cb2ee8cfa 100644
--- a/drivers/misc/m4sensorhub_als.c
+++ b/drivers/misc/m4sensorhub_als.c
@@ -40,18 +40,21 @@ struct m4als_driver_data {
struct m4sensorhub_data *m4;
struct mutex mutex; /* controls driver entry points */
struct input_dev *indev;
+ struct delayed_work m4als_work;
uint16_t luminosity;
int16_t samplerate;
int16_t latest_samplerate;
+ int16_t fastest_rate;
uint16_t status;
};
-
-static void m4als_isr(enum m4sensorhub_irqs int_event, void *handle)
+static void m4als_work_func(struct work_struct *work)
{
int err = 0;
- struct m4als_driver_data *dd = handle;
+ struct m4als_driver_data *dd = container_of(work,
+ struct m4als_driver_data,
+ m4als_work.work);
int size = 0;
uint16_t luminosity = 0;
@@ -80,6 +83,9 @@ static void m4als_isr(enum m4sensorhub_irqs int_event, void *handle)
input_event(dd->indev, EV_MSC, MSC_RAW, dd->luminosity);
input_sync(dd->indev);
+ if (dd->samplerate > 0)
+ schedule_delayed_work(&(dd->m4als_work),
+ msecs_to_jiffies(dd->samplerate));
m4als_isr_fail:
if (err < 0)
@@ -95,12 +101,15 @@ static int m4als_set_samplerate(struct m4als_driver_data *dd, int16_t rate)
int err = 0;
int size = 0;
+ if ((rate >= 0) && (rate <= dd->fastest_rate))
+ rate = dd->fastest_rate;
+
/* This variabled is to be always updated ireespective of the
transaction status */
dd->latest_samplerate = rate;
if (rate == dd->samplerate)
- goto m4als_change_interrupt_bit;
+ goto m4als_set_samplerate_fail;
size = m4sensorhub_reg_getsize(dd->m4, M4SH_REG_LIGHTSENSOR_SAMPLERATE);
if (size < 0) {
@@ -121,32 +130,11 @@ static int m4als_set_samplerate(struct m4als_driver_data *dd, int16_t rate)
err = -EBADE;
goto m4als_set_samplerate_fail;
}
+ cancel_delayed_work(&(dd->m4als_work));
dd->samplerate = rate;
-
-m4als_change_interrupt_bit:
- if (rate == -1) {
- if (dd->status & (1 << M4ALS_IRQ_ENABLED_BIT)) {
- err = m4sensorhub_irq_disable(dd->m4,
- M4SH_IRQ_LIGHTSENSOR_DATA_READY);
- if (err < 0) {
- m4als_err("%s: Failed to disable interrupt.\n",
- __func__);
- goto m4als_set_samplerate_fail;
- }
- dd->status = dd->status & ~(1 << M4ALS_IRQ_ENABLED_BIT);
- }
- } else {
- if (!(dd->status & (1 << M4ALS_IRQ_ENABLED_BIT))) {
- err = m4sensorhub_irq_enable(dd->m4,
- M4SH_IRQ_LIGHTSENSOR_DATA_READY);
- if (err < 0) {
- m4als_err("%s: Failed to enable interrupt.\n",
- __func__);
- goto m4als_set_samplerate_fail;
- }
- dd->status = dd->status | (1 << M4ALS_IRQ_ENABLED_BIT);
- }
- }
+ if (dd->samplerate > 0)
+ schedule_delayed_work(&(dd->m4als_work),
+ msecs_to_jiffies(rate));
m4als_set_samplerate_fail:
return err;
@@ -296,7 +284,10 @@ static void m4als_panic_restore(struct m4sensorhub_data *m4sensorhub,
m4als_err("%s: Wrote %d bytes instead of %d.\n",
__func__, err, size);
}
-
+ cancel_delayed_work(&(dd->m4als_work));
+ if (dd->samplerate > 0)
+ schedule_delayed_work(&(dd->m4als_work),
+ msecs_to_jiffies(dd->samplerate));
mutex_unlock(&(dd->mutex));
}
@@ -319,12 +310,7 @@ static int m4als_driver_init(struct init_calldata *p_arg)
goto m4als_driver_init_sysfs_fail;
}
- err = m4sensorhub_irq_register(dd->m4, M4SH_IRQ_LIGHTSENSOR_DATA_READY,
- m4als_isr, dd, 0);
- if (err < 0) {
- m4als_err("%s: Failed to register M4 IRQ.\n", __func__);
- goto m4als_driver_init_irq_fail;
- }
+ INIT_DELAYED_WORK(&(dd->m4als_work), m4als_work_func);
err = m4sensorhub_panic_register(dd->m4, PANICHDL_ALS_RESTORE,
m4als_panic_restore, dd);
@@ -332,8 +318,6 @@ static int m4als_driver_init(struct init_calldata *p_arg)
KDEBUG(M4SH_ERROR, "Als panic callback register failed\n");
goto m4als_driver_init_exit;
-m4als_driver_init_irq_fail:
- m4als_remove_sysfs(dd);
m4als_driver_init_sysfs_fail:
input_unregister_device(dd->indev);
m4als_driver_init_fail:
@@ -360,6 +344,7 @@ static int m4als_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, dd);
dd->samplerate = -1; /* We always start disabled */
dd->latest_samplerate = dd->samplerate;
+ dd->fastest_rate = 80; /* in milli secs */
dd->m4 = m4sensorhub_client_get_drvdata();
if (dd->m4 == NULL) {
@@ -389,13 +374,8 @@ static int __exit m4als_remove(struct platform_device *pdev)
struct m4als_driver_data *dd = platform_get_drvdata(pdev);
mutex_lock(&(dd->mutex));
+ cancel_delayed_work(&(dd->m4als_work));
m4als_remove_sysfs(dd);
- if (dd->status & (1 << M4ALS_IRQ_ENABLED_BIT)) {
- m4sensorhub_irq_disable(dd->m4,
- M4SH_IRQ_LIGHTSENSOR_DATA_READY);
- dd->status = dd->status & ~(1 << M4ALS_IRQ_ENABLED_BIT);
- }
- m4sensorhub_irq_unregister(dd->m4, M4SH_IRQ_LIGHTSENSOR_DATA_READY);
m4sensorhub_unregister_initcall(m4als_driver_init);
if (dd->indev != NULL)
input_unregister_device(dd->indev);
@@ -408,10 +388,8 @@ static int __exit m4als_remove(struct platform_device *pdev)
static int m4als_suspend(struct platform_device *pdev, pm_message_t state)
{
struct m4als_driver_data *dd = platform_get_drvdata(pdev);
- mutex_lock(&(dd->mutex));
if (m4als_set_samplerate(dd, dd->latest_samplerate) < 0)
m4als_err("%s: setrate retry failed\n", __func__);
- mutex_unlock(&(dd->mutex));
return 0;
}
diff --git a/drivers/misc/m4sensorhub_fusion.c b/drivers/misc/m4sensorhub_fusion.c
index c8d579fe4fe..f1ce277f2fe 100644
--- a/drivers/misc/m4sensorhub_fusion.c
+++ b/drivers/misc/m4sensorhub_fusion.c
@@ -45,17 +45,20 @@ struct m4fus_driver_data {
struct mutex mutex; /* controls driver entry points */
struct m4sensorhub_fusion_iio_data iiodat[M4FUS_NUM_FUSION_BUFFERS];
+ struct delayed_work m4fus_work;
int16_t samplerate;
int16_t latest_samplerate;
+ int16_t fastest_rate;
uint16_t status;
};
-
-static void m4fus_isr(enum m4sensorhub_irqs int_event, void *handle)
+static void m4fus_work_func(struct work_struct *work)
{
int err = 0;
- struct iio_dev *iio = handle;
- struct m4fus_driver_data *dd = iio_priv(iio);
+ struct m4fus_driver_data *dd = container_of(work,
+ struct m4fus_driver_data,
+ m4fus_work.work);
+ struct iio_dev *iio = platform_get_drvdata(dd->pdev);
int size = 0;
mutex_lock(&(dd->mutex));
@@ -129,6 +132,9 @@ static void m4fus_isr(enum m4sensorhub_irqs int_event, void *handle)
* in this one call (see the M4 passive driver).
*/
iio_push_to_buffers(iio, (unsigned char *)&(dd->iiodat[0]));
+ if (dd->samplerate > 0)
+ schedule_delayed_work(&(dd->m4fus_work),
+ msecs_to_jiffies(dd->samplerate));
m4fus_isr_fail:
if (err < 0)
@@ -145,9 +151,13 @@ static int m4fus_set_samplerate(struct iio_dev *iio, int16_t rate)
struct m4fus_driver_data *dd = iio_priv(iio);
int size = 0;
+ if ((rate >= 0) && (rate <= dd->fastest_rate))
+ rate = dd->fastest_rate;
+
dd->latest_samplerate = rate;
+
if (rate == dd->samplerate)
- goto m4fus_set_samplerate_irq_check;
+ goto m4fus_set_samplerate_fail;
size = m4sensorhub_reg_getsize(dd->m4, M4SH_REG_FUSION_SAMPLERATE);
err = m4sensorhub_reg_write(dd->m4, M4SH_REG_FUSION_SAMPLERATE,
@@ -162,33 +172,10 @@ static int m4fus_set_samplerate(struct iio_dev *iio, int16_t rate)
goto m4fus_set_samplerate_fail;
}
dd->samplerate = rate;
-
-m4fus_set_samplerate_irq_check:
- if (rate >= 0) {
- /* Enable the IRQ if necessary */
- if (!(dd->status & (1 << M4FUS_IRQ_ENABLED_BIT))) {
- err = m4sensorhub_irq_enable(dd->m4,
- M4SH_IRQ_FUSION_DATA_READY);
- if (err < 0) {
- m4fus_err("%s: Failed to enable irq.\n",
- __func__);
- goto m4fus_set_samplerate_fail;
- }
- dd->status = dd->status | (1 << M4FUS_IRQ_ENABLED_BIT);
- }
- } else {
- /* Disable the IRQ if necessary */
- if (dd->status & (1 << M4FUS_IRQ_ENABLED_BIT)) {
- err = m4sensorhub_irq_disable(dd->m4,
- M4SH_IRQ_FUSION_DATA_READY);
- if (err < 0) {
- m4fus_err("%s: Failed to disable irq.\n",
- __func__);
- goto m4fus_set_samplerate_fail;
- }
- dd->status = dd->status & ~(1 << M4FUS_IRQ_ENABLED_BIT);
- }
- }
+ cancel_delayed_work(&(dd->m4fus_work));
+ if (dd->samplerate > 0)
+ schedule_delayed_work(&(dd->m4fus_work),
+ msecs_to_jiffies(rate));
m4fus_set_samplerate_fail:
return err;
@@ -383,6 +370,10 @@ static void m4fus_panic_restore(struct m4sensorhub_data *m4sensorhub,
__func__, err, size);
}
+ cancel_delayed_work(&(dd->m4fus_work));
+ if (dd->samplerate > 0)
+ schedule_delayed_work(&(dd->m4fus_work),
+ msecs_to_jiffies(dd->samplerate));
mutex_unlock(&(dd->mutex));
}
@@ -401,12 +392,7 @@ static int m4fus_driver_init(struct init_calldata *p_arg)
goto m4fus_driver_init_fail;
}
- err = m4sensorhub_irq_register(dd->m4,
- M4SH_IRQ_FUSION_DATA_READY, m4fus_isr, iio, 0);
- if (err < 0) {
- m4fus_err("%s: Failed to register M4 IRQ.\n", __func__);
- goto m4fus_driver_init_fail;
- }
+ INIT_DELAYED_WORK(&(dd->m4fus_work), m4fus_work_func);
err = m4sensorhub_panic_register(dd->m4, PANICHDL_FUSION_RESTORE,
m4fus_panic_restore, dd);
@@ -441,6 +427,7 @@ static int m4fus_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, iio);
dd->samplerate = -1; /* We always start disabled */
dd->latest_samplerate = dd->samplerate;
+ dd->fastest_rate = 40;
err = m4fus_create_iiodev(iio); /* iio and dd are freed on fail */
if (err < 0) {
@@ -476,11 +463,7 @@ static int __exit m4fus_remove(struct platform_device *pdev)
goto m4fus_remove_exit;
mutex_lock(&(dd->mutex));
- if (dd->status & (1 << M4FUS_IRQ_ENABLED_BIT)) {
- m4sensorhub_irq_disable(dd->m4, M4SH_IRQ_FUSION_DATA_READY);
- dd->status = dd->status & ~(1 << M4FUS_IRQ_ENABLED_BIT);
- }
- m4sensorhub_irq_unregister(dd->m4, M4SH_IRQ_FUSION_DATA_READY);
+ cancel_delayed_work(&(dd->m4fus_work));
m4sensorhub_unregister_initcall(m4fus_driver_init);
m4fus_remove_iiodev(iio); /* dd is freed here */
@@ -492,10 +475,8 @@ static int m4fus_suspend(struct platform_device *pdev, pm_message_t state)
{
struct iio_dev *iio = platform_get_drvdata(pdev);
struct m4fus_driver_data *dd = iio_priv(iio);
- mutex_lock(&(dd->mutex));
if (m4fus_set_samplerate(iio, dd->latest_samplerate) < 0)
m4fus_err("%s: setrate retry failed\n", __func__);
- mutex_unlock(&(dd->mutex));
return 0;
}
diff --git a/drivers/misc/m4sensorhub_heartrate.c b/drivers/misc/m4sensorhub_heartrate.c
index 99b4a3d81f8..01fc5f210b7 100644
--- a/drivers/misc/m4sensorhub_heartrate.c
+++ b/drivers/misc/m4sensorhub_heartrate.c
@@ -46,19 +46,22 @@ struct m4hrt_driver_data {
struct mutex mutex; /* controls driver entry points */
struct m4sensorhub_heartrate_iio_data iiodat;
+ struct delayed_work m4hrt_work;
int32_t samplerate;
int32_t latest_samplerate;
+ int32_t fastest_rate;
uint16_t status;
uint8_t dbg_addr;
};
-
-static void m4hrt_isr(enum m4sensorhub_irqs int_event, void *handle)
+static void m4hrt_work_func(struct work_struct *work)
{
int err = 0;
- struct iio_dev *iio = handle;
- struct m4hrt_driver_data *dd = iio_priv(iio);
+ struct m4hrt_driver_data *dd = container_of(work,
+ struct m4hrt_driver_data,
+ m4hrt_work.work);
+ struct iio_dev *iio = platform_get_drvdata(dd->pdev);
int size = 0;
mutex_lock(&(dd->mutex));
@@ -91,6 +94,9 @@ static void m4hrt_isr(enum m4sensorhub_irqs int_event, void *handle)
dd->iiodat.timestamp = iio_get_time_ns();
iio_push_to_buffers(iio, (unsigned char *)&(dd->iiodat));
+ if (dd->samplerate > 0)
+ schedule_delayed_work(&(dd->m4hrt_work),
+ msecs_to_jiffies(dd->samplerate));
m4hrt_isr_fail:
if (err < 0)
@@ -107,10 +113,13 @@ static int m4hrt_set_samplerate(struct iio_dev *iio, int32_t rate)
struct m4hrt_driver_data *dd = iio_priv(iio);
int size = 0;
+ if ((rate >= 0) && (rate <= dd->fastest_rate))
+ rate = dd->fastest_rate;
+
dd->latest_samplerate = rate;
if (rate == dd->samplerate)
- goto m4hrt_set_samplerate_irq_check;
+ goto m4hrt_set_samplerate_fail;
size = m4sensorhub_reg_getsize(dd->m4,
M4SH_REG_HEARTRATE_APSAMPLERATE);
@@ -125,35 +134,11 @@ static int m4hrt_set_samplerate(struct iio_dev *iio, int32_t rate)
err = -EBADE;
goto m4hrt_set_samplerate_fail;
}
+ cancel_delayed_work(&(dd->m4hrt_work));
dd->samplerate = rate;
-
-m4hrt_set_samplerate_irq_check:
- if (rate >= 0) {
- /* Enable the IRQ if necessary */
- if (!(dd->status & (1 << M4HRT_IRQ_ENABLED_BIT))) {
- err = m4sensorhub_irq_enable(dd->m4,
- M4SH_IRQ_HEARTRATE_DATA_READY);
- if (err < 0) {
- m4hrt_err("%s: Failed to enable irq.\n",
- __func__);
- goto m4hrt_set_samplerate_fail;
- }
- dd->status = dd->status | (1 << M4HRT_IRQ_ENABLED_BIT);
- }
- } else {
- /* Disable the IRQ if necessary */
- if (dd->status & (1 << M4HRT_IRQ_ENABLED_BIT)) {
- err = m4sensorhub_irq_disable(dd->m4,
- M4SH_IRQ_HEARTRATE_DATA_READY);
- if (err < 0) {
- m4hrt_err("%s: Failed to disable irq.\n",
- __func__);
- goto m4hrt_set_samplerate_fail;
- }
- dd->status = dd->status & ~(1 << M4HRT_IRQ_ENABLED_BIT);
- }
- }
-
+ if (dd->samplerate > 0)
+ schedule_delayed_work(&(dd->m4hrt_work),
+ msecs_to_jiffies(dd->samplerate));
m4hrt_set_samplerate_fail:
return err;
}
@@ -504,7 +489,10 @@ static void m4hrt_panic_restore(struct m4sensorhub_data *m4sensorhub,
m4hrt_err("%s: Wrote %d bytes instead of %d.\n",
__func__, err, size);
}
-
+ cancel_delayed_work(&(dd->m4hrt_work));
+ if (dd->samplerate > 0)
+ schedule_delayed_work(&(dd->m4hrt_work),
+ msecs_to_jiffies(dd->samplerate));
mutex_unlock(&(dd->mutex));
}
@@ -523,12 +511,7 @@ static int m4hrt_driver_init(struct init_calldata *p_arg)
goto m4hrt_driver_init_fail;
}
- err = m4sensorhub_irq_register(dd->m4,
- M4SH_IRQ_HEARTRATE_DATA_READY, m4hrt_isr, iio, 0);
- if (err < 0) {
- m4hrt_err("%s: Failed to register M4 IRQ.\n", __func__);
- goto m4hrt_driver_init_fail;
- }
+ INIT_DELAYED_WORK(&(dd->m4hrt_work), m4hrt_work_func);
err = m4sensorhub_panic_register(dd->m4, PANICHDL_HEARTRATE_RESTORE,
m4hrt_panic_restore, dd);
@@ -563,6 +546,7 @@ static int m4hrt_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, iio);
dd->samplerate = -1; /* We always start disabled */
dd->latest_samplerate = dd->samplerate;
+ dd->fastest_rate = 80; /* in milli secs */
err = m4hrt_create_iiodev(iio); /* iio and dd are freed on fail */
if (err < 0) {
@@ -598,13 +582,7 @@ static int __exit m4hrt_remove(struct platform_device *pdev)
goto m4hrt_remove_exit;
mutex_lock(&(dd->mutex));
- if (dd->status & (1 << M4HRT_IRQ_ENABLED_BIT)) {
- m4sensorhub_irq_disable(dd->m4,
- M4SH_IRQ_HEARTRATE_DATA_READY);
- dd->status = dd->status & ~(1 << M4HRT_IRQ_ENABLED_BIT);
- }
- m4sensorhub_irq_unregister(dd->m4,
- M4SH_IRQ_HEARTRATE_DATA_READY);
+ cancel_delayed_work(&(dd->m4hrt_work));
m4sensorhub_unregister_initcall(m4hrt_driver_init);
m4hrt_remove_iiodev(iio); /* dd is freed here */
@@ -616,10 +594,8 @@ static int m4hrt_suspend(struct platform_device *pdev, pm_message_t state)
{
struct iio_dev *iio = platform_get_drvdata(pdev);
struct m4hrt_driver_data *dd = iio_priv(iio);
- mutex_lock(&(dd->mutex));
if (m4hrt_set_samplerate(iio, dd->latest_samplerate) < 0)
m4hrt_err("%s: setrate retry failed\n", __func__);
- mutex_unlock(&(dd->mutex));
return 0;
}
diff --git a/drivers/misc/m4sensorhub_mpu9150.c b/drivers/misc/m4sensorhub_mpu9150.c
index 0d852d4bdd4..52de21885d4 100644
--- a/drivers/misc/m4sensorhub_mpu9150.c
+++ b/drivers/misc/m4sensorhub_mpu9150.c
@@ -77,12 +77,11 @@ struct mpu9150_client {
struct mpu9150_gyro_data gyro_data;
struct mpu9150_compass_data compass_data;
struct mutex mutex; /* prevent concurrent thread access */
+ struct delayed_work mpu9150_work[NUM_TYPES];
+ signed short fastest_rate[NUM_TYPES];
};
struct mpu9150_client *misc_mpu9150_data;
-static int mpu9150_irq_enable_disable(struct mpu9150_client *mpu9150_client_data,
- enum mpu9150_sensor type, int flag);
-
static int mpu9150_client_open(struct inode *inode, struct file *file)
{
int err = 0;
@@ -144,22 +143,30 @@ static void m4_report_mpu9150_inputevent(
static void m4_set_mpu9150_delay(struct mpu9150_client *mpu9150_client_data,
int delay, enum mpu9150_sensor type)
{
- mpu9150_client_data->latest_samplerate[type] = delay;
+ struct mpu9150_client *dd = mpu9150_client_data;
+
+ if ((delay >= 0) && (delay <= dd->fastest_rate[type]))
+ delay = dd->fastest_rate[type];
- if (delay != mpu9150_client_data->samplerate[type]) {
+ dd->latest_samplerate[type] = delay;
+ if (delay != dd->samplerate[type]) {
switch (type) {
case TYPE_GYRO:
- m4sensorhub_reg_write(mpu9150_client_data->m4sensorhub,
- M4SH_REG_GYRO_SAMPLERATE, (char *)&delay, m4sh_no_mask);
+ m4sensorhub_reg_write(dd->m4sensorhub,
+ M4SH_REG_GYRO_SAMPLERATE,
+ (char *)&delay, m4sh_no_mask);
break;
case TYPE_ACCEL:
- m4sensorhub_reg_write(mpu9150_client_data->m4sensorhub,
- M4SH_REG_ACCEL_SAMPLERATE, (char *)&delay, m4sh_no_mask);
+ m4sensorhub_reg_write(dd->m4sensorhub,
+ M4SH_REG_ACCEL_SAMPLERATE,
+ (char *)&delay, m4sh_no_mask);
break;
case TYPE_COMPASS:
- m4sensorhub_reg_write(mpu9150_client_data->m4sensorhub,
- M4SH_REG_COMPASS_SAMPLERATE, (char *)&delay, m4sh_no_mask);
+ m4sensorhub_reg_write(dd->m4sensorhub,
+ M4SH_REG_COMPASS_SAMPLERATE,
+ (char *)&delay, m4sh_no_mask);
break;
+
default:
return;
break;
@@ -168,8 +175,12 @@ static void m4_set_mpu9150_delay(struct mpu9150_client *mpu9150_client_data,
" %d to %d\n", __func__, type,
mpu9150_client_data->samplerate[type],
delay);
+ cancel_delayed_work(&(dd->mpu9150_work[type]));
+ dd->samplerate[type] = delay;
+ if (dd->samplerate[type] > 0)
+ schedule_delayed_work(&(dd->mpu9150_work[type]),
+ msecs_to_jiffies(delay));
- mpu9150_client_data->samplerate[type] = delay;
}
}
@@ -224,48 +235,64 @@ static void m4_read_mpu9150_data(struct mpu9150_client *mpu9150_client_data,
default:
break;
}
-
}
-static void m4_handle_mpu9150_gyro_irq(enum m4sensorhub_irqs int_event,
- void *mpu9150_data)
+static void m4gyro_work_func(struct work_struct *work)
{
- struct mpu9150_client *mpu9150_client_data = mpu9150_data;
-
- mutex_lock(&(mpu9150_client_data->mutex));
-
- m4_read_mpu9150_data(mpu9150_client_data, TYPE_GYRO);
- m4_report_mpu9150_inputevent(mpu9150_client_data, TYPE_GYRO);
+ struct mpu9150_client *dd =
+ container_of(work,
+ struct mpu9150_client,
+ mpu9150_work[TYPE_GYRO].work);
+ signed short rate;
- mutex_unlock(&(mpu9150_client_data->mutex));
+ mutex_lock(&(dd->mutex));
+ m4_read_mpu9150_data(dd, TYPE_GYRO);
+ m4_report_mpu9150_inputevent(dd, TYPE_GYRO);
+ rate = dd->samplerate[TYPE_GYRO];
+ if (rate > 0)
+ schedule_delayed_work(&(dd->mpu9150_work[TYPE_GYRO]),
+ msecs_to_jiffies(rate));
+ mutex_unlock(&(dd->mutex));
}
-static void m4_handle_mpu9150_accel_irq(enum m4sensorhub_irqs int_event,
- void *mpu9150_data)
-{
- struct mpu9150_client *mpu9150_client_data = mpu9150_data;
-
- mutex_lock(&(mpu9150_client_data->mutex));
- m4_read_mpu9150_data(mpu9150_client_data, TYPE_ACCEL);
- m4_report_mpu9150_inputevent(mpu9150_client_data, TYPE_ACCEL);
+static void m4accel_work_func(struct work_struct *work)
+{
+ struct mpu9150_client *dd =
+ container_of(work,
+ struct mpu9150_client,
+ mpu9150_work[TYPE_ACCEL].work);
+ signed short rate;
- mutex_unlock(&(mpu9150_client_data->mutex));
+ mutex_lock(&(dd->mutex));
+ m4_read_mpu9150_data(dd, TYPE_ACCEL);
+ m4_report_mpu9150_inputevent(dd, TYPE_ACCEL);
+ rate = dd->samplerate[TYPE_ACCEL];
+ if (rate > 0)
+ schedule_delayed_work(&(dd->mpu9150_work[TYPE_ACCEL]),
+ msecs_to_jiffies(rate));
+ mutex_unlock(&(dd->mutex));
}
-static void m4_handle_mpu9150_compass_irq(enum m4sensorhub_irqs int_event,
- void *mpu9150_data)
+static void m4compass_work_func(struct work_struct *work)
{
- struct mpu9150_client *mpu9150_client_data = mpu9150_data;
+ struct mpu9150_client *dd =
+ container_of(work,
+ struct mpu9150_client,
+ mpu9150_work[TYPE_COMPASS].work);
+ signed short rate;
- mutex_lock(&(mpu9150_client_data->mutex));
-
- m4_read_mpu9150_data(mpu9150_client_data, TYPE_COMPASS);
- m4_report_mpu9150_inputevent(mpu9150_client_data, TYPE_COMPASS);
-
- mutex_unlock(&(mpu9150_client_data->mutex));
+ mutex_lock(&(dd->mutex));
+ m4_read_mpu9150_data(dd, TYPE_COMPASS);
+ m4_report_mpu9150_inputevent(dd, TYPE_COMPASS);
+ rate = dd->samplerate[TYPE_COMPASS];
+ if (rate > 0)
+ schedule_delayed_work(&(dd->mpu9150_work[TYPE_COMPASS]),
+ msecs_to_jiffies(rate));
+ mutex_unlock(&(dd->mutex));
}
+
static ssize_t m4_mpu9150_write_accel_setdelay(struct device *dev,
struct device_attribute *attr,
const char *buf, size_t count)
@@ -287,21 +314,7 @@ static ssize_t m4_mpu9150_write_accel_setdelay(struct device *dev,
}
mutex_lock(&(misc_mpu9150_data->mutex));
-
m4_set_mpu9150_delay(misc_mpu9150_data, scanresult, TYPE_ACCEL);
-
- if (scanresult == -1) {
- mpu9150_irq_enable_disable(
- misc_mpu9150_data, TYPE_ACCEL,
- SENSOR_IRQ_DISABLE
- );
- } else {
- mpu9150_irq_enable_disable(
- misc_mpu9150_data, TYPE_ACCEL,
- SENSOR_IRQ_ENABLE
- );
- }
-
mutex_unlock(&(misc_mpu9150_data->mutex));
return count;
@@ -332,17 +345,6 @@ static ssize_t m4_mpu9150_write_gyro_setdelay(struct device *dev,
mutex_lock(&(misc_mpu9150_data->mutex));
m4_set_mpu9150_delay(misc_mpu9150_data, scanresult, TYPE_GYRO);
- if (scanresult == -1) {
- mpu9150_irq_enable_disable(
- misc_mpu9150_data, TYPE_GYRO,
- SENSOR_IRQ_DISABLE
- );
- } else {
- mpu9150_irq_enable_disable(
- misc_mpu9150_data, TYPE_GYRO,
- SENSOR_IRQ_ENABLE
- );
- }
mutex_unlock(&(misc_mpu9150_data->mutex));
@@ -374,17 +376,6 @@ static ssize_t m4_mpu9150_write_compass_setdelay(struct device *dev,
mutex_lock(&(misc_mpu9150_data->mutex));
m4_set_mpu9150_delay(misc_mpu9150_data, scanresult, TYPE_COMPASS);
- if (scanresult == -1) {
- mpu9150_irq_enable_disable(
- misc_mpu9150_data, TYPE_COMPASS,
- SENSOR_IRQ_DISABLE
- );
- } else {
- mpu9150_irq_enable_disable(
- misc_mpu9150_data, TYPE_COMPASS,
- SENSOR_IRQ_ENABLE
- );
- }
mutex_unlock(&(misc_mpu9150_data->mutex));
@@ -556,130 +547,12 @@ static struct miscdevice mpu9150_client_miscdrv = {
.fops = &mpu9150_client_fops,
};
-static int mpu9150_irq_init(struct mpu9150_client *mpu9150_client_data)
-{
- int ret = -1;
-
- ret = m4sensorhub_irq_register(mpu9150_client_data->m4sensorhub,
- M4SH_IRQ_GYRO_DATA_READY,
- m4_handle_mpu9150_gyro_irq,
- mpu9150_client_data, 0);
- if (ret < 0) {
- KDEBUG(M4SH_ERROR, "Error registering int %d (%d)\n",
- M4SH_IRQ_GYRO_DATA_READY, ret);
- return ret;
- }
- ret = m4sensorhub_irq_register(mpu9150_client_data->m4sensorhub,
- M4SH_IRQ_ACCEL_DATA_READY,
- m4_handle_mpu9150_accel_irq,
- mpu9150_client_data, 0);
- if (ret < 0) {
- KDEBUG(M4SH_ERROR, "Error registering int %d (%d)\n",
- M4SH_IRQ_ACCEL_DATA_READY, ret);
- goto unregister_gyro_irq;
- }
- ret = m4sensorhub_irq_register(mpu9150_client_data->m4sensorhub,
- M4SH_IRQ_COMPASS_DATA_READY,
- m4_handle_mpu9150_compass_irq,
- mpu9150_client_data, 0);
- if (ret < 0) {
- KDEBUG(M4SH_ERROR, "Error registering int %d (%d)\n",
- M4SH_IRQ_COMPASS_DATA_READY, ret);
- goto unregister_accel_irq;
- }
- return ret;
-
-unregister_accel_irq:
- m4sensorhub_irq_unregister(mpu9150_client_data->m4sensorhub,
- M4SH_IRQ_ACCEL_DATA_READY);
-unregister_gyro_irq:
- m4sensorhub_irq_unregister(mpu9150_client_data->m4sensorhub,
- M4SH_IRQ_GYRO_DATA_READY);
- return ret;
-}
-
-static void mpu9150_irq_deinit(struct mpu9150_client *mpu9150_client_data)
-{
- m4sensorhub_irq_unregister(mpu9150_client_data->m4sensorhub,
- M4SH_IRQ_COMPASS_DATA_READY);
- m4sensorhub_irq_unregister(mpu9150_client_data->m4sensorhub,
- M4SH_IRQ_ACCEL_DATA_READY);
- m4sensorhub_irq_unregister(mpu9150_client_data->m4sensorhub,
- M4SH_IRQ_GYRO_DATA_READY);
-}
-
-static int mpu9150_irq_enable_disable(struct mpu9150_client *mpu9150_client_data,
- enum mpu9150_sensor type, int flag)
-{
- int ret = 0;
- int irq_status = 0;
-
- switch (type) {
- case TYPE_GYRO:
- irq_status = m4sensorhub_irq_enable_get(
- mpu9150_client_data->m4sensorhub,
- M4SH_IRQ_GYRO_DATA_READY);
- if (flag && (!irq_status)) {
- ret = m4sensorhub_irq_enable(
- mpu9150_client_data->m4sensorhub,
- M4SH_IRQ_GYRO_DATA_READY);
- if (ret < 0) {
- KDEBUG(M4SH_ERROR, "Error enabling int %d (%d)\n",
- M4SH_IRQ_GYRO_DATA_READY, ret);
- return ret;
- }
- } else if ((!flag) && irq_status)
- m4sensorhub_irq_disable(
- mpu9150_client_data->m4sensorhub,
- M4SH_IRQ_GYRO_DATA_READY);
- break;
- case TYPE_ACCEL:
- irq_status = m4sensorhub_irq_enable_get(
- mpu9150_client_data->m4sensorhub,
- M4SH_IRQ_ACCEL_DATA_READY);
- if (flag && (!irq_status)) {
- ret = m4sensorhub_irq_enable(
- mpu9150_client_data->m4sensorhub,
- M4SH_IRQ_ACCEL_DATA_READY);
- if (ret < 0) {
- KDEBUG(M4SH_ERROR, "Error enabling int %d (%d)\n",
- M4SH_IRQ_ACCEL_DATA_READY, ret);
- return ret;
- }
- } else if ((!flag) && irq_status)
- m4sensorhub_irq_disable(
- mpu9150_client_data->m4sensorhub,
- M4SH_IRQ_ACCEL_DATA_READY);
- break;
- case TYPE_COMPASS:
- irq_status = m4sensorhub_irq_enable_get(
- mpu9150_client_data->m4sensorhub,
- M4SH_IRQ_COMPASS_DATA_READY);
- if (flag && (!irq_status)) {
- ret = m4sensorhub_irq_enable(
- mpu9150_client_data->m4sensorhub,
- M4SH_IRQ_COMPASS_DATA_READY);
- if (ret < 0) {
- KDEBUG(M4SH_ERROR, "Error enabling int %d (%d)\n",
- M4SH_IRQ_COMPASS_DATA_READY, ret);
- return ret;
- }
- } else if ((!flag) && irq_status)
- m4sensorhub_irq_disable(
- mpu9150_client_data->m4sensorhub,
- M4SH_IRQ_COMPASS_DATA_READY);
- break;
- default:
- ret = -EINVAL;
- break;
- }
- return ret;
-}
-
static void mpu9150_panic_restore(struct m4sensorhub_data *m4sensorhub,
void *data)
{
struct mpu9150_client *dd = (struct mpu9150_client *)data;
+ int type;
+ signed short rate;
if (dd == NULL) {
KDEBUG(M4SH_INFO, "%s: Driver data is null,unable to restore\n",
@@ -688,36 +561,37 @@ static void mpu9150_panic_restore(struct m4sensorhub_data *m4sensorhub,
}
mutex_lock(&(dd->mutex));
-
KDEBUG(M4SH_INFO, "Executing mpu9150 panic restore\n");
- m4_set_mpu9150_delay(dd, dd->samplerate[TYPE_ACCEL], TYPE_ACCEL);
- m4_set_mpu9150_delay(dd, dd->samplerate[TYPE_GYRO], TYPE_GYRO);
- m4_set_mpu9150_delay(dd, dd->samplerate[TYPE_COMPASS], TYPE_COMPASS);
-
+ for (type = 0; type < NUM_TYPES; type++) {
+ rate = dd->samplerate[type];
+ m4_set_mpu9150_delay(dd, rate, type);
+ cancel_delayed_work(&(dd->mpu9150_work[type]));
+ if (rate > 0)
+ schedule_delayed_work(&(dd->mpu9150_work[type]),
+ msecs_to_jiffies(rate));
+ }
mutex_unlock(&(dd->mutex));
}
static int mpu9150_driver_init(struct init_calldata *p_arg)
{
int ret;
+ struct mpu9150_client *dd = p_arg->p_data;
- mutex_lock(&(misc_mpu9150_data->mutex));
-
- ret = mpu9150_irq_init(misc_mpu9150_data);
- if (ret < 0) {
- KDEBUG(M4SH_ERROR, "mpu9150 irq init failed\n");
- goto driver_init_exit;
- }
-
- ret = m4sensorhub_panic_register(misc_mpu9150_data->m4sensorhub,
+ mutex_lock(&(dd->mutex));
+ INIT_DELAYED_WORK(&(dd->mpu9150_work[TYPE_ACCEL]), m4accel_work_func);
+ INIT_DELAYED_WORK(&(dd->mpu9150_work[TYPE_COMPASS]),
+ m4compass_work_func);
+ INIT_DELAYED_WORK(&(dd->mpu9150_work[TYPE_GYRO]),
+ m4gyro_work_func);
+ ret = m4sensorhub_panic_register(dd->m4sensorhub,
PANICHDL_MPU9150_RESTORE,
mpu9150_panic_restore,
- misc_mpu9150_data);
+ dd);
if (ret < 0)
KDEBUG(M4SH_ERROR, "HR panic callback register failed\n");
-driver_init_exit:
- mutex_unlock(&(misc_mpu9150_data->mutex));
+ mutex_unlock(&(dd->mutex));
return ret;
}
@@ -746,6 +620,9 @@ static int mpu9150_client_probe(struct platform_device *pdev)
mpu9150_client_data->samplerate[TYPE_GYRO];
mpu9150_client_data->latest_samplerate[TYPE_COMPASS] =
mpu9150_client_data->samplerate[TYPE_COMPASS];
+ mpu9150_client_data->fastest_rate[TYPE_ACCEL] = 40;
+ mpu9150_client_data->fastest_rate[TYPE_GYRO] = 40;
+ mpu9150_client_data->fastest_rate[TYPE_COMPASS] = 40;
mpu9150_client_data->input_dev = input_allocate_device();
if (!mpu9150_client_data->input_dev) {
@@ -841,7 +718,9 @@ static int __exit mpu9150_client_remove(struct platform_device *pdev)
#ifdef MPU9150_DEBUG
sysfs_remove_group(&pdev->dev.kobj, &mpu9150_group);
#endif
- mpu9150_irq_deinit(mpu9150_client_data);
+ cancel_delayed_work(&(mpu9150_client_data->mpu9150_work[TYPE_COMPASS]));
+ cancel_delayed_work(&(mpu9150_client_data->mpu9150_work[TYPE_ACCEL]));
+ cancel_delayed_work(&(mpu9150_client_data->mpu9150_work[TYPE_GYRO]));
m4sensorhub_unregister_initcall(mpu9150_driver_init);
misc_mpu9150_data = NULL;
misc_deregister(&mpu9150_client_miscdrv);
@@ -865,18 +744,16 @@ static int mpu9150_client_suspend(struct platform_device *pdev,
return 0;
}
- mutex_lock(&(dd->mutex));
m4_set_mpu9150_delay(dd, dd->latest_samplerate[TYPE_ACCEL], TYPE_ACCEL);
m4_set_mpu9150_delay(dd, dd->latest_samplerate[TYPE_GYRO], TYPE_GYRO);
m4_set_mpu9150_delay(dd, dd->latest_samplerate[TYPE_COMPASS],
TYPE_COMPASS);
-
- mutex_unlock(&(dd->mutex));
-
return 0;
}
+
+
static struct of_device_id m4mpu9150_match_tbl[] = {
{ .compatible = "mot,m4mpu9150" },
{},
diff --git a/drivers/misc/m4sensorhub_pedometer.c b/drivers/misc/m4sensorhub_pedometer.c
index ff3a0c1e913..56b2d912f7a 100644
--- a/drivers/misc/m4sensorhub_pedometer.c
+++ b/drivers/misc/m4sensorhub_pedometer.c
@@ -47,9 +47,9 @@ struct m4ped_driver_data {
struct m4sensorhub_pedometer_iio_data iiodat;
struct m4sensorhub_pedometer_iio_data base_dat;
+ struct delayed_work m4ped_work;
int16_t samplerate;
- int16_t latest_samplerate;
-
+ int16_t fastest_rate;
uint16_t status;
};
@@ -162,15 +162,21 @@ m4ped_read_fail:
return err;
}
-static void m4ped_isr(enum m4sensorhub_irqs int_event, void *handle)
+static void m4ped_work_func(struct work_struct *work)
{
int err = 0;
- struct iio_dev *iio = handle;
- struct m4ped_driver_data *dd = iio_priv(iio);
+ struct m4ped_driver_data *dd = container_of(work,
+ struct m4ped_driver_data,
+ m4ped_work.work);
+ struct iio_dev *iio = platform_get_drvdata(dd->pdev);
+
mutex_lock(&(dd->mutex));
err = m4ped_read_report_data(iio, dd);
if (err < 0)
m4ped_err("%s: Failed with error code %d.\n", __func__, err);
+ if (dd->samplerate > 0)
+ schedule_delayed_work(&(dd->m4ped_work),
+ msecs_to_jiffies(dd->samplerate));
mutex_unlock(&(dd->mutex));
return;
}
@@ -180,60 +186,17 @@ static int m4ped_set_samplerate(struct iio_dev *iio, int16_t rate)
int err = 0;
struct m4ped_driver_data *dd = iio_priv(iio);
- /*
- * Currently, there is no concept of setting a sample rate for this
- * sensor, so this function only enables/disables interrupt reporting.
- */
- dd->latest_samplerate = rate;
+ if ((rate >= 0) && (rate <= dd->fastest_rate))
+ rate = dd->fastest_rate;
+
if (rate == dd->samplerate)
goto m4ped_set_samplerate_fail;
- if (rate >= 0) {
- /* Enable the IRQ if necessary */
- if (!(dd->status & (1 << M4PED_IRQ_ENABLED_BIT))) {
- err = m4sensorhub_irq_enable(dd->m4,
- M4SH_IRQ_PEDOMETER_DATA_READY);
- if (err < 0) {
- m4ped_err("%s: Failed to enable ped irq.\n",
- __func__);
- goto m4ped_set_samplerate_fail;
- }
-
- err = m4sensorhub_irq_enable(dd->m4,
- M4SH_IRQ_ACTIVITY_CHANGE);
- if (err < 0) {
- m4ped_err("%s: Failed to enable act irq.\n",
- __func__);
- goto m4ped_set_samplerate_fail;
- }
-
- dd->status = dd->status | (1 << M4PED_IRQ_ENABLED_BIT);
- dd->samplerate = rate;
- }
- } else {
- /* Disable the IRQ if necessary */
- if (dd->status & (1 << M4PED_IRQ_ENABLED_BIT)) {
- err = m4sensorhub_irq_disable(dd->m4,
- M4SH_IRQ_PEDOMETER_DATA_READY);
- if (err < 0) {
- m4ped_err("%s: Failed to disable ped irq.\n",
- __func__);
- goto m4ped_set_samplerate_fail;
- }
-
- err = m4sensorhub_irq_disable(dd->m4,
- M4SH_IRQ_ACTIVITY_CHANGE);
- if (err < 0) {
- m4ped_err("%s: Failed to disable act irq.\n",
- __func__);
- goto m4ped_set_samplerate_fail;
- }
-
- dd->status = dd->status & ~(1 << M4PED_IRQ_ENABLED_BIT);
- dd->samplerate = rate;
- }
- }
-
+ cancel_delayed_work(&(dd->m4ped_work));
+ dd->samplerate = rate;
+ if (dd->samplerate > 0)
+ schedule_delayed_work(&(dd->m4ped_work),
+ msecs_to_jiffies(rate));
m4ped_set_samplerate_fail:
return err;
}
@@ -668,6 +631,10 @@ static void m4ped_panic_restore(struct m4sensorhub_data *m4sensorhub,
goto m4ped_panic_restore_fail;
}
}
+ cancel_delayed_work(&(dd->m4ped_work));
+ if (dd->samplerate > 0)
+ schedule_delayed_work(&(dd->m4ped_work),
+ msecs_to_jiffies(dd->samplerate));
m4ped_panic_restore_fail:
mutex_unlock(&(dd->mutex));
@@ -688,19 +655,7 @@ static int m4ped_driver_init(struct init_calldata *p_arg)
goto m4ped_driver_init_fail;
}
- err = m4sensorhub_irq_register(dd->m4,
- M4SH_IRQ_PEDOMETER_DATA_READY, m4ped_isr, iio, 0);
- if (err < 0) {
- m4ped_err("%s: Failed to register M4 PED IRQ.\n", __func__);
- goto m4ped_driver_init_fail;
- }
-
- err = m4sensorhub_irq_register(dd->m4,
- M4SH_IRQ_ACTIVITY_CHANGE, m4ped_isr, iio, 0);
- if (err < 0) {
- m4ped_err("%s: Failed to register M4 ACT IRQ.\n", __func__);
- goto m4ped_driver_init_irq_act_fail;
- }
+ INIT_DELAYED_WORK(&(dd->m4ped_work), m4ped_work_func);
err = m4sensorhub_panic_register(dd->m4, PANICHDL_PEDOMETER_RESTORE,
m4ped_panic_restore, dd);
@@ -709,8 +664,6 @@ static int m4ped_driver_init(struct init_calldata *p_arg)
goto m4ped_driver_init_exit;
-m4ped_driver_init_irq_act_fail:
- m4sensorhub_irq_unregister(dd->m4, M4SH_IRQ_PEDOMETER_DATA_READY);
m4ped_driver_init_fail:
m4ped_err("%s: Init failed with error code %d.\n", __func__, err);
m4ped_driver_init_exit:
@@ -736,7 +689,7 @@ static int m4ped_probe(struct platform_device *pdev)
mutex_init(&(dd->mutex));
platform_set_drvdata(pdev, iio);
dd->samplerate = -1; /* We always start disabled */
- dd->latest_samplerate = dd->samplerate;
+ dd->fastest_rate = 1000; /* in milli secs */
dd->status = dd->status | (1 << M4PED_FEATURE_ENABLED_BIT);
err = m4ped_create_iiodev(iio); /* iio and dd are freed on fail */
@@ -773,17 +726,6 @@ static int __exit m4ped_remove(struct platform_device *pdev)
goto m4ped_remove_exit;
mutex_lock(&(dd->mutex));
- if (dd->status & (1 << M4PED_IRQ_ENABLED_BIT)) {
- m4sensorhub_irq_disable(dd->m4,
- M4SH_IRQ_PEDOMETER_DATA_READY);
- m4sensorhub_irq_disable(dd->m4,
- M4SH_IRQ_ACTIVITY_CHANGE);
- dd->status = dd->status & ~(1 << M4PED_IRQ_ENABLED_BIT);
- }
- m4sensorhub_irq_unregister(dd->m4,
- M4SH_IRQ_PEDOMETER_DATA_READY);
- m4sensorhub_irq_unregister(dd->m4,
- M4SH_IRQ_ACTIVITY_CHANGE);
m4sensorhub_unregister_initcall(m4ped_driver_init);
m4ped_remove_iiodev(iio); /* dd is freed here */
@@ -791,17 +733,6 @@ m4ped_remove_exit:
return 0;
}
-static int m4ped_suspend(struct platform_device *pdev, pm_message_t state)
-{
- struct iio_dev *iio = platform_get_drvdata(pdev);
- struct m4ped_driver_data *dd = iio_priv(iio);
- mutex_lock(&(dd->mutex));
- if (m4ped_set_samplerate(iio, dd->latest_samplerate) < 0)
- m4ped_err("%s: setrate retry failed\n", __func__);
- mutex_unlock(&(dd->mutex));
- return 0;
-}
-
static struct of_device_id m4pedometer_match_tbl[] = {
{ .compatible = "mot,m4pedometer" },
{},
@@ -811,7 +742,7 @@ static struct platform_driver m4ped_driver = {
.probe = m4ped_probe,
.remove = __exit_p(m4ped_remove),
.shutdown = NULL,
- .suspend = m4ped_suspend,
+ .suspend = NULL,
.resume = NULL,
.driver = {
.name = M4PED_DRIVER_NAME,