static int k3g_resume(struct device *dev) { int err = 0; struct i2c_client *client = to_i2c_client(dev); struct k3g_data *k3g_data = i2c_get_clientdata(client); struct k3g_platform_data *pdata; if(DEBUG_FUNC_TRACE & debug_mask) printk(KERN_INFO "%s: line %d\n", __func__, __LINE__); pdata = client->dev.platform_data; if (pdata->power_on){ if(DEBUG_GEN_INFO & debug_mask) printk(KERN_INFO "%s: goes to resume, power on\n", __func__); pdata->power_on(1<<SENSOR_TYPE_GYROSCOPE); mdelay(1); } if (k3g_data->enable) { mutex_lock(&k3g_data->lock); mdelay(300); k3g_restart_fifo(k3g_data); if (!k3g_data->interruptible) hrtimer_start(&k3g_data->timer, k3g_data->polling_delay, HRTIMER_MODE_REL); err = i2c_smbus_write_i2c_block_data(client, CTRL_REG1 | AC, sizeof(k3g_data->ctrl_regs), k3g_data->ctrl_regs); mutex_unlock(&k3g_data->lock); } return err; }
static int k3g_report_gyro_values(struct k3g_data *k3g_data) { int res; struct k3g_t data; gyro_debug("GYRO sensor enter function %s\n",__FUNCTION__); res = k3g_read_gyro_values(k3g_data->client, &data, k3g_data->entries + k3g_data->drop_next_event); if (res < 0) return res; res = k3g_read_fifo_status(k3g_data); k3g_data->drop_next_event = !res; if (res >= 31 - k3g_data->entries) { /* reset fifo to start again - data isn't trustworthy, * our locked read might not have worked and we * could have done i2c read in mid register update */ return k3g_restart_fifo(k3g_data); } input_report_rel(k3g_data->input_dev, REL_RX, data.x); input_report_rel(k3g_data->input_dev, REL_RY, data.y); input_report_rel(k3g_data->input_dev, REL_RZ, data.z); input_sync(k3g_data->input_dev); gyro_debug("GYRO sensor report x %d\n",data.x); gyro_debug("GYRO sensor report y %d\n",data.y); gyro_debug("GYRO sensor report z %d\n",data.z); return res; }
static int k3g_report_gyro_values(struct k3g_data *k3g_data) { int res; struct k3g_t data; if(DEBUG_FUNC_TRACE & debug_mask) printk(KERN_INFO "%s: line %d\n", __func__, __LINE__); res = k3g_read_gyro_values(k3g_data->client, &data, k3g_data->entries + k3g_data->drop_next_event); if (res < 0) return res; res = k3g_read_fifo_status(k3g_data); if(DEBUG_DEV_STATUS& debug_mask) printk(KERN_INFO "[k3g] read_fifo_status(%d)\n", res); k3g_data->drop_next_event = !res; if(DEBUG_DEV_STATUS& debug_mask) printk(KERN_INFO "[k3g] entries=%d\n", k3g_data->entries); if (res >= 31 - k3g_data->entries) { /* reset fifo to start again - data isn't trustworthy, * our locked read might not have worked and we * could have done i2c read in mid register update */ if(DEBUG_DEV_STATUS& debug_mask) printk(KERN_INFO "[k3g] call restart_fifo, entries=%d\n", k3g_data->entries); return k3g_restart_fifo(k3g_data); } #ifndef CONFIG_LGE_SENSOR_FUSION input_report_rel(k3g_data->input_dev, REL_RX, data.x); input_report_rel(k3g_data->input_dev, REL_RY, data.y); input_report_rel(k3g_data->input_dev, REL_RZ, data.z); input_sync(k3g_data->input_dev); #else k3g_gyro_data[0] = (int) data.x; k3g_gyro_data[1] = (int) data.y; k3g_gyro_data[2] = (int) data.z; #endif #ifdef CONFIG_MACH_LGE_I_BOARD_VZW //BEGIN:seungkwan.jung gyro_xyz[0] = data.x; gyro_xyz[1] = data.y; gyro_xyz[2] = data.z; //END:seungkwan.jung #endif if(DEBUG_DEV_DEBOUNCE & debug_mask) printk(KERN_INFO "%s: [k3g] x(%d), y(%d), z(%d)\n", __func__, data.x, data.y, data.z); report_cnt++; return res; }
static ssize_t k3g_set_delay(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { struct k3g_data *k3g_data = dev_get_drvdata(dev); int odr_value = ODR105_BW25; int res = 0; int i; u64 delay_ns; u8 ctrl; if(DEBUG_FUNC_TRACE & debug_mask) printk(KERN_INFO "%s: line %d\n", __func__, __LINE__); res = strict_strtoll(buf, 10, &delay_ns); if (res < 0) return res; if(DEBUG_FUNC_TRACE & debug_mask) printk(KERN_INFO "%s: line %d\n", __func__, __LINE__); mutex_lock(&k3g_data->lock); if (!k3g_data->interruptible) hrtimer_cancel(&k3g_data->timer); else disable_irq(k3g_data->client->irq); /* round to the nearest supported ODR that is less than * the requested value */ for (i = 0; i < ARRAY_SIZE(odr_delay_table); i++) if (delay_ns <= odr_delay_table[i].delay_ns) { odr_value = odr_delay_table[i].odr; delay_ns = odr_delay_table[i].delay_ns; k3g_data->time_to_read = delay_ns; k3g_data->entries = 1; break; } if (delay_ns >= odr_delay_table[3].delay_ns) { if (delay_ns >= MAX_DELAY) { k3g_data->entries = MAX_ENTRY; delay_ns = MAX_DELAY; } else { do_div(delay_ns, odr_delay_table[3].delay_ns); k3g_data->entries = delay_ns; } k3g_data->time_to_read = odr_delay_table[3].delay_ns; } if (odr_value != (k3g_data->ctrl_regs[0] & ODR_MASK)) { ctrl = (k3g_data->ctrl_regs[0] & ~ODR_MASK); ctrl |= odr_value; k3g_data->ctrl_regs[0] = ctrl; res = i2c_smbus_write_byte_data(k3g_data->client, CTRL_REG1, ctrl); } /* we see a noise in the first sample or two after we * change rates. this delay helps eliminate that noise. */ msleep((u32)delay_ns * 2 / NSEC_PER_MSEC); /* (re)start fifo */ k3g_restart_fifo(k3g_data); if (!k3g_data->interruptible) { delay_ns = k3g_data->entries * k3g_data->time_to_read; k3g_data->polling_delay = ns_to_ktime(delay_ns); if (k3g_data->enable) hrtimer_start(&k3g_data->timer, k3g_data->polling_delay, HRTIMER_MODE_REL); } else { enable_irq(k3g_data->client->irq); } mutex_unlock(&k3g_data->lock); return size; }
static ssize_t k3g_set_enable(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { int err = 0; struct k3g_platform_data *pdata; bool new_enable; struct k3g_data *k3g_data = dev_get_drvdata(dev); struct i2c_client *client = to_i2c_client(dev); pdata = k3g_i2c_client->dev.platform_data; if(pdata == NULL) { dev_err(&client->dev, "failed to read platform data\n"); err = -ENODEV; return err; } if(DEBUG_FUNC_TRACE & debug_mask) printk(KERN_INFO "%s: line %d - enable %s\n", __func__, __LINE__, buf); if (sysfs_streq(buf, "1")) { new_enable = true; if(DEBUG_FUNC_TRACE & debug_mask||DEBUG_DEBUG_SYSFS & debug_mask) printk(KERN_INFO "%s: line %d - enable\n", __func__, __LINE__); } else if (sysfs_streq(buf, "0")) { new_enable = false; if(DEBUG_FUNC_TRACE & debug_mask||DEBUG_DEBUG_SYSFS & debug_mask) printk(KERN_INFO "%s: line %d - disable\n", __func__, __LINE__); } else { pr_debug("%s: invalid value %d\n", __func__, *buf); return -EINVAL; } if (new_enable == k3g_data->enable) { return size; } mutex_lock(&k3g_data->lock); if (new_enable) { if(pdata->power_on){ if(DEBUG_FUNC_TRACE & debug_mask) printk(KERN_INFO "%s: line %d, call power_on", __func__, __LINE__); pdata->power_on(1<<SENSOR_TYPE_GYROSCOPE); mdelay(1); } /* turning on */ err = i2c_smbus_write_i2c_block_data(k3g_data->client, CTRL_REG1 | AC, sizeof(k3g_data->ctrl_regs), k3g_data->ctrl_regs); if (err < 0) { err = -EIO; if(DEBUG_FUNC_TRACE & debug_mask) printk(KERN_INFO "%s: line %d, failed turn on\n", __func__, __LINE__); goto unlock; } mdelay(300); /* reset fifo entries */ err = k3g_restart_fifo(k3g_data); if (err < 0) { err = -EIO; goto turn_off; } if (k3g_data->interruptible) { enable_irq(k3g_data->client->irq); if(DEBUG_FUNC_TRACE & debug_mask) printk(KERN_INFO "%s: line %d, enable interrupt\n", __func__, __LINE__); } else { set_polling_delay(k3g_data, 0); hrtimer_start(&k3g_data->timer, k3g_data->polling_delay, HRTIMER_MODE_REL); if(DEBUG_FUNC_TRACE & debug_mask) printk(KERN_INFO "%s: line %d, set_polling_delay\n", __func__, __LINE__); } report_cnt = 0; } else { if (k3g_data->interruptible) { printk(KERN_INFO "%s: line %d -disable_irq\n", __func__, __LINE__); disable_irq(k3g_data->client->irq); } else { printk(KERN_INFO "%s: line %d - cancel timer\n", __func__, __LINE__); hrtimer_cancel(&k3g_data->timer); cancel_work_sync(&k3g_data->work); flush_workqueue(k3g_data->k3g_wq); } /* turning off */ err = i2c_smbus_write_byte_data(k3g_data->client, CTRL_REG1, 0x00); if (err < 0) { printk(KERN_INFO "%s: line %d - i2c error\n", __func__, __LINE__); goto unlock; } } k3g_data->enable = new_enable; turn_off: if (err < 0) i2c_smbus_write_byte_data(k3g_data->client, CTRL_REG1, 0x00); unlock: mutex_unlock(&k3g_data->lock); return err ? err : size; }
static ssize_t k3g_set_enable(struct device *dev, struct device_attribute *attr, const char *buf, size_t size) { int err = 0; struct k3g_data *k3g_data = dev_get_drvdata(dev); bool new_enable; gyro_debug("GYRO sensor enter function %s\n",__FUNCTION__); if (sysfs_streq(buf, "1")) new_enable = true; else if (sysfs_streq(buf, "0")) new_enable = false; else { pr_debug("%s: invalid value %d\n", __func__, *buf); return -EINVAL; } if (new_enable == k3g_data->enable) return size; mutex_lock(&k3g_data->lock); if (new_enable) { /* turning on */ err = i2c_smbus_write_i2c_block_data(k3g_data->client, CTRL_REG1 | AC, sizeof(k3g_data->ctrl_regs), k3g_data->ctrl_regs); if (err < 0) { err = -EIO; goto unlock; } /* reset fifo entries */ err = k3g_restart_fifo(k3g_data); if (err < 0) { err = -EIO; goto turn_off; } k3g_data->timer_enable = 1; k3g_data->work_enable = 1; if (k3g_data->interruptible) enable_irq(k3g_data->client->irq); else { set_polling_delay(k3g_data, 0); hrtimer_start(&k3g_data->timer, k3g_data->polling_delay, HRTIMER_MODE_REL); } } else { k3g_data->timer_enable = 0; k3g_data->work_enable = 0; if (k3g_data->interruptible) disable_irq(k3g_data->client->irq); else { hrtimer_cancel(&k3g_data->timer); cancel_work_sync(&k3g_data->work); } /* turning off */ err = i2c_smbus_write_byte_data(k3g_data->client, CTRL_REG1, 0x00); if (err < 0) goto unlock; } k3g_data->enable = new_enable; turn_off: if (err < 0) i2c_smbus_write_byte_data(k3g_data->client, CTRL_REG1, 0x00); unlock: mutex_unlock(&k3g_data->lock); return err ? err : size; }