static int mmc328x_magnetic_resume(struct early_suspend *handler) { unsigned char data[16] = {0}; atomic_set(&suspend_flag,RESUME); #ifdef MMC328X_SENSOR_DEBUG printk("mmc328x resume mode :%d \n",suspend_flag.counter); #endif if (g_client){ kfree(g_client); } g_client = omap_gpio_i2c_init(OMAP_GPIO_FM_SDA , OMAP_GPIO_FM_SCL, MMC328X_I2C_ADDR, 200); msleep(MMC328X_DELAY_RRM); /* send SET/RESET cmd to mag sensor first of all */ #ifdef CONFIG_SENSORS_MMC328X data[0] = MMC328X_REG_CTRL; data[1] = MMC328X_CTRL_RRM; if (mmc328x_i2c_tx_data(data, 2) < 0) { } msleep(MMC328X_DELAY_RRM); data[0] = MMC328X_REG_CTRL; data[1] = MMC328X_CTRL_TM; if (mmc328x_i2c_tx_data(data, 2) < 0) { } msleep(5*MMC328X_DELAY_TM); #endif data[0] = MMC328X_REG_CTRL; data[1] = MMC328X_CTRL_RM; if (mmc328x_i2c_tx_data(data, 2) < 0) { /* assume RM always success */ } #ifndef CONFIG_SENSORS_MMC328X /* wait external capacitor charging done for next RM */ msleep(MMC328X_DELAY_RM); #else msleep(10*MMC328X_DELAY_RM); data[0] = MMC328X_REG_CTRL; data[1] = MMC328X_CTRL_TM; if (mmc328x_i2c_tx_data(data, 2) < 0) { } #endif return 0; }
int memsic_api_suspend ( void *mlsl_handle, struct ext_slave_platform_data *pdata ) { #if 0 unsigned char data[2] = {0}; data[0] = MMC328X_REG_CTRL; data[1] = 0; if (mmc328x_i2c_tx_data(mlsl_handle,pdata,data, 2) < 0) { return -1; } msleep(MMC328X_DELAY_RM); data[0] = MMC328X_REG_CTRL; data[1] = 0; mmc328x_i2c_tx_data(mlsl_handle,pdata,data, 2); msleep(MMC328X_DELAY_TM); #endif return 0; }
static ssize_t mmc328x_poweron(struct device *dev, struct device_attribute *attr, char *buf) { int count; unsigned char data[16] = {0}; data[0] = MMC328X_REG_CTRL; data[1] = MMC328X_CTRL_TM; if (mmc328x_i2c_tx_data(data, 2) < 0) { count = sprintf(buf,"%d\n", POWER_OFF); return -EFAULT; } /* wait TM done for coming data read */ msleep(MMC328X_DELAY_TM); count = sprintf(buf,"%d\n", POWER_ON); return count; }
int memsic_api_read ( void *mlsl_handle, struct ext_slave_platform_data *pdata, unsigned char* raw_data, int *accuracy ) { unsigned char data[6] = {0}; int MD_times = 0; data[0] = MMC328X_REG_CTRL; data[1] = MMC328X_CTRL_TM; mmc328x_i2c_tx_data(mlsl_handle,pdata,data, 2); msleep(MMC328X_DELAY_TM); data[0] = MMC328X_REG_DS; if (mmc328x_i2c_rx_data(mlsl_handle,pdata,data, 1) < 0) { return -EFAULT; } while (!(data[0] & 0x01)) { msleep(1); data[0] = MMC328X_REG_DS; if (mmc328x_i2c_rx_data(mlsl_handle,pdata,data, 1) < 0) { return -EFAULT; } if (data[0] & 0x01) break; MD_times++; if (MD_times > 2) { return -EFAULT; } } data[0] = MMC328X_REG_DATA; if (mmc328x_i2c_rx_data(mlsl_handle,pdata,data, 6) < 0) { return -EFAULT; } memcpy(raw_data, data, sizeof(unsigned char)*6); *accuracy = 0; return 0; }
static int mmc328x_init_probe(struct platform_device *pdev) { unsigned char data[16] = {0}; int res = 0; int ret33 = 0; if (get_hw_revision() == 0x09) { printk("[SENSOR] hw_revision : 0x09\n "); vreg_sensor = regulator_get(NULL, "vmmc2"); ret33 = regulator_enable(vreg_sensor); if (ret33) { printk("[SENSOR] Error, %s: vreg enable failed (%d)\n", __func__, ret33); } } pr_info("mmc328x driver: probe\n"); g_client = omap_gpio_i2c_init(OMAP_GPIO_FM_SDA , OMAP_GPIO_FM_SCL, MMC328X_I2C_ADDR, 200); res = misc_register(&mmc328x_device); if (res) { pr_err("%s: mmc328x_device register failed\n", __FUNCTION__); goto out; } res = device_create_file(mmc328x_device.this_device, &dev_attr_mmc328x); if (res) { pr_err("%s: device_create_file failed\n", __FUNCTION__); goto out_deregister; } res = sysfs_create_group(&mmc328x_device.this_device->kobj,&mmc328x_group); if (res < 0){ pr_info("failed to create sysfs files\n"); goto out_sysinfo; } /* send SET/RESET cmd to mag sensor first of all */ #ifdef CONFIG_SENSORS_MMC328X data[0] = MMC328X_REG_CTRL; data[1] = MMC328X_CTRL_RRM; if (mmc328x_i2c_tx_data(data, 2) < 0) { } msleep(MMC328X_DELAY_RRM); data[0] = MMC328X_REG_CTRL; data[1] = MMC328X_CTRL_TM; if (mmc328x_i2c_tx_data(data, 2) < 0) { } msleep(5*MMC328X_DELAY_TM); #endif data[0] = MMC328X_REG_CTRL; data[1] = MMC328X_CTRL_RM; if (mmc328x_i2c_tx_data(data, 2) < 0) { /* assume RM always success */ } #ifndef CONFIG_SENSORS_MMC328X /* wait external capacitor charging done for next RM */ msleep(MMC328X_DELAY_RM); #else msleep(10*MMC328X_DELAY_RM); data[0] = MMC328X_REG_CTRL; data[1] = MMC328X_CTRL_TM; if (mmc328x_i2c_tx_data(data, 2) < 0) { } #endif #if defined(CONFIG_HAS_EARLYSUSPEND) early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN + 1; early_suspend.suspend = (void *)mmc328x_magnetic_suspend; early_suspend.resume = (void *)mmc328x_magnetic_resume; register_early_suspend(&early_suspend); #endif return 0; out_sysinfo: sysfs_remove_group(&mmc328x_device.this_device->kobj,&mmc328x_group); out_deregister: misc_deregister(&mmc328x_device); out: return res; }
static ssize_t mmc328x_readxyz(struct device *dev, struct device_attribute *attr, char *buf) { int count; int vec[3] = {0}; unsigned char data[16] = {0}; int MD_times = 0; /* do RM every MMC328X_RRM_INTV times read */ if (!(read_idx % MMC328X_RRM_INTV)) { #ifdef CONFIG_SENSORS_MMC328X data[0] = MMC328X_REG_CTRL; data[1] = MMC328X_CTRL_RRM; mmc328x_i2c_tx_data(data, 2); msleep(MMC328X_DELAY_RRM); #endif /* RM */ data[0] = MMC328X_REG_CTRL; data[1] = MMC328X_CTRL_RM; /* not check return value here, assume it always OK */ mmc328x_i2c_tx_data(data, 2); /* wait external capacitor charging done for next RM */ msleep(MMC328X_DELAY_RM); } /* send TM cmd before read */ data[0] = MMC328X_REG_CTRL; data[1] = MMC328X_CTRL_TM; /* not check return value here, assume it always OK */ mmc328x_i2c_tx_data(data, 2); /* wait TM done for coming data read */ msleep(MMC328X_DELAY_TM); #if READMD /* Read MD */ data[0] = MMC328X_REG_DS; if (mmc328x_i2c_rx_data(data, 1) < 0) { sprintf(buf,"%d,%d,%d\n", -1, -1, -1 ); return -EFAULT; } while (!(data[0] & 0x01)) { msleep(1); /* Read MD again*/ data[0] = MMC328X_REG_DS; if (mmc328x_i2c_rx_data(data, 1) < 0) { sprintf(buf,"%d,%d,%d\n", -1, -1, -1 ); return -EFAULT; } if (data[0] & 0x01) break; MD_times++; if (MD_times > 2) { #ifdef MMC328X_SENSOR_DEBUG printk("TM not work!!"); #endif sprintf(buf,"%d,%d,%d\n", -1, -1, -1 ); return -EFAULT; } } #endif /* read xyz raw data */ read_idx++; data[0] = MMC328X_REG_DATA; if (mmc328x_i2c_rx_data(data, 6) < 0) { sprintf(buf,"%d,%d,%d\n", -1, -1, -1 ); return -EFAULT; } vec[0] = data[1] << 8 | data[0]; vec[1] = data[3] << 8 | data[2]; vec[2] = data[5] << 8 | data[4]; #ifdef MMC328X_SENSOR_DEBUG printk("[X - %04x] [Y - %04x] [Z - %04x]\n", vec[0], vec[1], vec[2]); #endif count = sprintf(buf,"%d,%d,%d\n", vec[0], vec[1], vec[2] ); return count; }
static int mmc328x_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg) { void __user *pa = (void __user *)arg; unsigned char data[16] = {0}; int vec[3] = {0}; int MD_times = 0; short flag; switch (cmd) { case MMC328X_IOC_TM: data[0] = MMC328X_REG_CTRL; data[1] = MMC328X_CTRL_TM; if (mmc328x_i2c_tx_data(data, 2) < 0) { return -EFAULT; } /* wait TM done for coming data read */ msleep(MMC328X_DELAY_TM); break; case MMC328X_IOC_RM: data[0] = MMC328X_REG_CTRL; data[1] = MMC328X_CTRL_RM; if (mmc328x_i2c_tx_data(data, 2) < 0) { return -EFAULT; } /* wait external capacitor charging done for next SET*/ msleep(MMC328X_DELAY_RM); break; case MMC328X_IOC_RRM: data[0] = MMC328X_REG_CTRL; data[1] = MMC328X_CTRL_RRM; if (mmc328x_i2c_tx_data(data, 2) < 0) { return -EFAULT; } /* wait external capacitor charging done for next RRM */ msleep(MMC328X_DELAY_RM); break; case MMC328X_IOC_READ: data[0] = MMC328X_REG_DATA; if (mmc328x_i2c_rx_data(data, 6) < 0) { return -EFAULT; } vec[0] = data[1] << 8 | data[0]; vec[1] = data[3] << 8 | data[2]; vec[2] = 8192 - (data[5] << 8 | data[4]); //vec[2] = data[5] << 8 | data[4]; #ifdef MMC328X_SENSOR_DEBUG printk("[X - %04x] [Y - %04x] [Z - %04x]\n", vec[0], vec[1], vec[2]); #endif if (copy_to_user(pa, vec, sizeof(vec))) { return -EFAULT; } break; case MMC328X_IOC_READXYZ: /* do RM every MMC328X_RRM_INTV times read */ if (!(read_idx % MMC328X_RRM_INTV)) { #ifdef CONFIG_SENSORS_MMC328X data[0] = MMC328X_REG_CTRL; data[1] = MMC328X_CTRL_RRM; mmc328x_i2c_tx_data(data, 2); msleep(MMC328X_DELAY_RRM); #endif /* RM */ data[0] = MMC328X_REG_CTRL; data[1] = MMC328X_CTRL_RM; /* not check return value here, assume it always OK */ mmc328x_i2c_tx_data(data, 2); /* wait external capacitor charging done for next RM */ msleep(MMC328X_DELAY_RM); } /* send TM cmd before read */ data[0] = MMC328X_REG_CTRL; data[1] = MMC328X_CTRL_TM; /* not check return value here, assume it always OK */ mmc328x_i2c_tx_data(data, 2); /* wait TM done for coming data read */ msleep(MMC328X_DELAY_TM); #if READMD /* Read MD */ data[0] = MMC328X_REG_DS; if (mmc328x_i2c_rx_data(data, 1) < 0) { return -EFAULT; } while (!(data[0] & 0x01)) { msleep(1); /* Read MD again*/ data[0] = MMC328X_REG_DS; if (mmc328x_i2c_rx_data(data, 1) < 0) { return -EFAULT; } if (data[0] & 0x01) break; MD_times++; if (MD_times > 2) { #ifdef MMC328X_SENSOR_DEBUG printk("TM not work!!"); #endif return -EFAULT; } } #endif /* read xyz raw data */ read_idx++; data[0] = MMC328X_REG_DATA; if (mmc328x_i2c_rx_data(data, 6) < 0) { return -EFAULT; } vec[0] = data[1] << 8 | data[0]; vec[1] = data[3] << 8 | data[2]; vec[2] = 8192 - (data[5] << 8 | data[4]); //vec[2] = data[5] << 8 | data[4]; #ifdef MMC328X_SENSOR_DEBUG printk("[X - %04x] [Y - %04x] [Z - %04x]\n", vec[0], vec[1], vec[2]); #endif if (copy_to_user(pa, vec, sizeof(vec))) { return -EFAULT; } break; case MMC328X_IOC_READSUSPEND: flag = atomic_read(&suspend_flag); if (copy_to_user(pa, &flag, sizeof(flag))) return -EFAULT; break; default: break; } return 0; }