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;
}
Exemple #2
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;
}
Exemple #4
0
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;
}