Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 78537c3b authored by Takashi Iwai's avatar Takashi Iwai Committed by Guenter Roeck
Browse files

hwmon: (lis3) Add support for new LIS3DC / HP3DC chip



A new version of LIS3 chip has slight incompatibilities from former
versions.  This patch adds the minimal support for it.

Signed-off-by: default avatarTakashi Iwai <tiwai@suse.de>
Signed-off-by: default avatarGuenter Roeck <guenter.roeck@ericsson.com>
parent 9401ba13
Loading
Loading
Loading
Loading
+27 −8
Original line number Original line Diff line number Diff line
@@ -138,6 +138,7 @@ static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z)
/* conversion btw sampling rate and the register values */
/* conversion btw sampling rate and the register values */
static int lis3_12_rates[4] = {40, 160, 640, 2560};
static int lis3_12_rates[4] = {40, 160, 640, 2560};
static int lis3_8_rates[2] = {100, 400};
static int lis3_8_rates[2] = {100, 400};
static int lis3_3dc_rates[16] = {0, 1, 10, 25, 50, 100, 200, 400, 1600, 5000};


/* ODR is Output Data Rate */
/* ODR is Output Data Rate */
static int lis3lv02d_get_odr(void)
static int lis3lv02d_get_odr(void)
@@ -156,6 +157,9 @@ static int lis3lv02d_set_odr(int rate)
	u8 ctrl;
	u8 ctrl;
	int i, len, shift;
	int i, len, shift;


	if (!rate)
		return -EINVAL;

	lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl);
	lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl);
	ctrl &= ~lis3_dev.odr_mask;
	ctrl &= ~lis3_dev.odr_mask;
	len = 1 << hweight_long(lis3_dev.odr_mask); /* # of possible values */
	len = 1 << hweight_long(lis3_dev.odr_mask); /* # of possible values */
@@ -172,19 +176,25 @@ static int lis3lv02d_set_odr(int rate)


static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
{
{
	u8 reg;
	u8 ctlreg, reg;
	s16 x, y, z;
	s16 x, y, z;
	u8 selftest;
	u8 selftest;
	int ret;
	int ret;


	mutex_lock(&lis3->mutex);
	mutex_lock(&lis3->mutex);
	if (lis3_dev.whoami == WAI_3DC) {
		ctlreg = CTRL_REG4;
		selftest = CTRL4_ST0;
	} else {
		ctlreg = CTRL_REG1;
		if (lis3_dev.whoami == WAI_12B)
		if (lis3_dev.whoami == WAI_12B)
			selftest = CTRL1_ST;
			selftest = CTRL1_ST;
		else
		else
			selftest = CTRL1_STP;
			selftest = CTRL1_STP;
	}


	lis3->read(lis3, CTRL_REG1, &reg);
	lis3->read(lis3, ctlreg, &reg);
	lis3->write(lis3, CTRL_REG1, (reg | selftest));
	lis3->write(lis3, ctlreg, (reg | selftest));
	msleep(lis3->pwron_delay / lis3lv02d_get_odr());
	msleep(lis3->pwron_delay / lis3lv02d_get_odr());


	/* Read directly to avoid axis remap */
	/* Read directly to avoid axis remap */
@@ -193,7 +203,7 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
	z = lis3->read_data(lis3, OUTZ);
	z = lis3->read_data(lis3, OUTZ);


	/* back to normal settings */
	/* back to normal settings */
	lis3->write(lis3, CTRL_REG1, reg);
	lis3->write(lis3, ctlreg, reg);
	msleep(lis3->pwron_delay / lis3lv02d_get_odr());
	msleep(lis3->pwron_delay / lis3lv02d_get_odr());


	results[0] = x - lis3->read_data(lis3, OUTX);
	results[0] = x - lis3->read_data(lis3, OUTX);
@@ -674,6 +684,15 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
		dev->odr_mask = CTRL1_DR;
		dev->odr_mask = CTRL1_DR;
		dev->scale = LIS3_SENSITIVITY_8B;
		dev->scale = LIS3_SENSITIVITY_8B;
		break;
		break;
	case WAI_3DC:
		printk(KERN_INFO DRIVER_NAME ": 8 bits 3DC sensor found\n");
		dev->read_data = lis3lv02d_read_8;
		dev->mdps_max_val = 128;
		dev->pwron_delay = LIS3_PWRON_DELAY_WAI_8B;
		dev->odrs = lis3_3dc_rates;
		dev->odr_mask = CTRL1_ODR0|CTRL1_ODR1|CTRL1_ODR2|CTRL1_ODR3;
		dev->scale = LIS3_SENSITIVITY_8B;
		break;
	default:
	default:
		printk(KERN_ERR DRIVER_NAME
		printk(KERN_ERR DRIVER_NAME
			": unknown sensor type 0x%X\n", dev->whoami);
			": unknown sensor type 0x%X\n", dev->whoami);
+17 −0
Original line number Original line Diff line number Diff line
@@ -45,6 +45,7 @@ enum lis3_reg {
	CTRL_REG1	= 0x20,
	CTRL_REG1	= 0x20,
	CTRL_REG2	= 0x21,
	CTRL_REG2	= 0x21,
	CTRL_REG3	= 0x22,
	CTRL_REG3	= 0x22,
	CTRL_REG4	= 0x23,
	HP_FILTER_RESET	= 0x23,
	HP_FILTER_RESET	= 0x23,
	STATUS_REG	= 0x27,
	STATUS_REG	= 0x27,
	OUTX_L		= 0x28,
	OUTX_L		= 0x28,
@@ -93,6 +94,7 @@ enum lis3lv02d_reg {
};
};


enum lis3_who_am_i {
enum lis3_who_am_i {
	WAI_3DC		= 0x33,	/* 8 bits: LIS3DC, HP3DC */
	WAI_12B		= 0x3A, /* 12 bits: LIS3LV02D[LQ]... */
	WAI_12B		= 0x3A, /* 12 bits: LIS3LV02D[LQ]... */
	WAI_8B		= 0x3B, /* 8 bits: LIS[23]02D[LQ]... */
	WAI_8B		= 0x3B, /* 8 bits: LIS[23]02D[LQ]... */
	WAI_6B		= 0x52, /* 6 bits: LIS331DLF - not supported */
	WAI_6B		= 0x52, /* 6 bits: LIS331DLF - not supported */
@@ -118,6 +120,13 @@ enum lis3lv02d_ctrl1_8b {
	CTRL1_DR	= 0x80,
	CTRL1_DR	= 0x80,
};
};


enum lis3lv02d_ctrl1_3dc {
	CTRL1_ODR0	= 0x10,
	CTRL1_ODR1	= 0x20,
	CTRL1_ODR2	= 0x40,
	CTRL1_ODR3	= 0x80,
};

enum lis3lv02d_ctrl2 {
enum lis3lv02d_ctrl2 {
	CTRL2_DAS	= 0x01,
	CTRL2_DAS	= 0x01,
	CTRL2_SIM	= 0x02,
	CTRL2_SIM	= 0x02,
@@ -129,6 +138,14 @@ enum lis3lv02d_ctrl2 {
	CTRL2_FS	= 0x80, /* Full Scale selection */
	CTRL2_FS	= 0x80, /* Full Scale selection */
};
};


enum lis3lv02d_ctrl4_3dc {
	CTRL4_SIM	= 0x01,
	CTRL4_ST0	= 0x02,
	CTRL4_ST1	= 0x04,
	CTRL4_FS0	= 0x10,
	CTRL4_FS1	= 0x20,
};

enum lis302d_ctrl2 {
enum lis302d_ctrl2 {
	HP_FF_WU2	= 0x08,
	HP_FF_WU2	= 0x08,
	HP_FF_WU1	= 0x04,
	HP_FF_WU1	= 0x04,