aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/hwmon/lis3lv02d.c35
-rw-r--r--drivers/hwmon/lis3lv02d.h17
2 files changed, 44 insertions, 8 deletions
diff --git a/drivers/hwmon/lis3lv02d.c b/drivers/hwmon/lis3lv02d.c
index fc591ae53107..ef7510d83603 100644
--- a/drivers/hwmon/lis3lv02d.c
+++ b/drivers/hwmon/lis3lv02d.c
@@ -138,6 +138,7 @@ static void lis3lv02d_get_xyz(struct lis3lv02d *lis3, int *x, int *y, int *z)
138/* conversion btw sampling rate and the register values */ 138/* conversion btw sampling rate and the register values */
139static int lis3_12_rates[4] = {40, 160, 640, 2560}; 139static int lis3_12_rates[4] = {40, 160, 640, 2560};
140static int lis3_8_rates[2] = {100, 400}; 140static int lis3_8_rates[2] = {100, 400};
141static int lis3_3dc_rates[16] = {0, 1, 10, 25, 50, 100, 200, 400, 1600, 5000};
141 142
142/* ODR is Output Data Rate */ 143/* ODR is Output Data Rate */
143static int lis3lv02d_get_odr(void) 144static int lis3lv02d_get_odr(void)
@@ -156,6 +157,9 @@ static int lis3lv02d_set_odr(int rate)
156 u8 ctrl; 157 u8 ctrl;
157 int i, len, shift; 158 int i, len, shift;
158 159
160 if (!rate)
161 return -EINVAL;
162
159 lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl); 163 lis3_dev.read(&lis3_dev, CTRL_REG1, &ctrl);
160 ctrl &= ~lis3_dev.odr_mask; 164 ctrl &= ~lis3_dev.odr_mask;
161 len = 1 << hweight_long(lis3_dev.odr_mask); /* # of possible values */ 165 len = 1 << hweight_long(lis3_dev.odr_mask); /* # of possible values */
@@ -172,19 +176,25 @@ static int lis3lv02d_set_odr(int rate)
172 176
173static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3]) 177static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
174{ 178{
175 u8 reg; 179 u8 ctlreg, reg;
176 s16 x, y, z; 180 s16 x, y, z;
177 u8 selftest; 181 u8 selftest;
178 int ret; 182 int ret;
179 183
180 mutex_lock(&lis3->mutex); 184 mutex_lock(&lis3->mutex);
181 if (lis3_dev.whoami == WAI_12B) 185 if (lis3_dev.whoami == WAI_3DC) {
182 selftest = CTRL1_ST; 186 ctlreg = CTRL_REG4;
183 else 187 selftest = CTRL4_ST0;
184 selftest = CTRL1_STP; 188 } else {
189 ctlreg = CTRL_REG1;
190 if (lis3_dev.whoami == WAI_12B)
191 selftest = CTRL1_ST;
192 else
193 selftest = CTRL1_STP;
194 }
185 195
186 lis3->read(lis3, CTRL_REG1, &reg); 196 lis3->read(lis3, ctlreg, &reg);
187 lis3->write(lis3, CTRL_REG1, (reg | selftest)); 197 lis3->write(lis3, ctlreg, (reg | selftest));
188 msleep(lis3->pwron_delay / lis3lv02d_get_odr()); 198 msleep(lis3->pwron_delay / lis3lv02d_get_odr());
189 199
190 /* Read directly to avoid axis remap */ 200 /* Read directly to avoid axis remap */
@@ -193,7 +203,7 @@ static int lis3lv02d_selftest(struct lis3lv02d *lis3, s16 results[3])
193 z = lis3->read_data(lis3, OUTZ); 203 z = lis3->read_data(lis3, OUTZ);
194 204
195 /* back to normal settings */ 205 /* back to normal settings */
196 lis3->write(lis3, CTRL_REG1, reg); 206 lis3->write(lis3, ctlreg, reg);
197 msleep(lis3->pwron_delay / lis3lv02d_get_odr()); 207 msleep(lis3->pwron_delay / lis3lv02d_get_odr());
198 208
199 results[0] = x - lis3->read_data(lis3, OUTX); 209 results[0] = x - lis3->read_data(lis3, OUTX);
@@ -674,6 +684,15 @@ int lis3lv02d_init_device(struct lis3lv02d *dev)
674 dev->odr_mask = CTRL1_DR; 684 dev->odr_mask = CTRL1_DR;
675 dev->scale = LIS3_SENSITIVITY_8B; 685 dev->scale = LIS3_SENSITIVITY_8B;
676 break; 686 break;
687 case WAI_3DC:
688 printk(KERN_INFO DRIVER_NAME ": 8 bits 3DC sensor found\n");
689 dev->read_data = lis3lv02d_read_8;
690 dev->mdps_max_val = 128;
691 dev->pwron_delay = LIS3_PWRON_DELAY_WAI_8B;
692 dev->odrs = lis3_3dc_rates;
693 dev->odr_mask = CTRL1_ODR0|CTRL1_ODR1|CTRL1_ODR2|CTRL1_ODR3;
694 dev->scale = LIS3_SENSITIVITY_8B;
695 break;
677 default: 696 default:
678 printk(KERN_ERR DRIVER_NAME 697 printk(KERN_ERR DRIVER_NAME
679 ": unknown sensor type 0x%X\n", dev->whoami); 698 ": unknown sensor type 0x%X\n", dev->whoami);
diff --git a/drivers/hwmon/lis3lv02d.h b/drivers/hwmon/lis3lv02d.h
index 854091380e33..62c6652eb9d5 100644
--- a/drivers/hwmon/lis3lv02d.h
+++ b/drivers/hwmon/lis3lv02d.h
@@ -45,6 +45,7 @@ enum lis3_reg {
45 CTRL_REG1 = 0x20, 45 CTRL_REG1 = 0x20,
46 CTRL_REG2 = 0x21, 46 CTRL_REG2 = 0x21,
47 CTRL_REG3 = 0x22, 47 CTRL_REG3 = 0x22,
48 CTRL_REG4 = 0x23,
48 HP_FILTER_RESET = 0x23, 49 HP_FILTER_RESET = 0x23,
49 STATUS_REG = 0x27, 50 STATUS_REG = 0x27,
50 OUTX_L = 0x28, 51 OUTX_L = 0x28,
@@ -93,6 +94,7 @@ enum lis3lv02d_reg {
93}; 94};
94 95
95enum lis3_who_am_i { 96enum lis3_who_am_i {
97 WAI_3DC = 0x33, /* 8 bits: LIS3DC, HP3DC */
96 WAI_12B = 0x3A, /* 12 bits: LIS3LV02D[LQ]... */ 98 WAI_12B = 0x3A, /* 12 bits: LIS3LV02D[LQ]... */
97 WAI_8B = 0x3B, /* 8 bits: LIS[23]02D[LQ]... */ 99 WAI_8B = 0x3B, /* 8 bits: LIS[23]02D[LQ]... */
98 WAI_6B = 0x52, /* 6 bits: LIS331DLF - not supported */ 100 WAI_6B = 0x52, /* 6 bits: LIS331DLF - not supported */
@@ -118,6 +120,13 @@ enum lis3lv02d_ctrl1_8b {
118 CTRL1_DR = 0x80, 120 CTRL1_DR = 0x80,
119}; 121};
120 122
123enum lis3lv02d_ctrl1_3dc {
124 CTRL1_ODR0 = 0x10,
125 CTRL1_ODR1 = 0x20,
126 CTRL1_ODR2 = 0x40,
127 CTRL1_ODR3 = 0x80,
128};
129
121enum lis3lv02d_ctrl2 { 130enum lis3lv02d_ctrl2 {
122 CTRL2_DAS = 0x01, 131 CTRL2_DAS = 0x01,
123 CTRL2_SIM = 0x02, 132 CTRL2_SIM = 0x02,
@@ -129,6 +138,14 @@ enum lis3lv02d_ctrl2 {
129 CTRL2_FS = 0x80, /* Full Scale selection */ 138 CTRL2_FS = 0x80, /* Full Scale selection */
130}; 139};
131 140
141enum lis3lv02d_ctrl4_3dc {
142 CTRL4_SIM = 0x01,
143 CTRL4_ST0 = 0x02,
144 CTRL4_ST1 = 0x04,
145 CTRL4_FS0 = 0x10,
146 CTRL4_FS1 = 0x20,
147};
148
132enum lis302d_ctrl2 { 149enum lis302d_ctrl2 {
133 HP_FF_WU2 = 0x08, 150 HP_FF_WU2 = 0x08,
134 HP_FF_WU1 = 0x04, 151 HP_FF_WU1 = 0x04,