summaryrefslogtreecommitdiff
path: root/driver/als_si114x.h
blob: e3a19895ba3796a1c8e84df5278375e8632d6a3f (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
/* Copyright 2015 The Chromium OS Authors. All rights reserved.
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 *
 * Silicon Image SI1141/SI1142 light sensor driver
 */

/*
 * si114x.c - Support for Silabs si114x combined ambient light and
 * proximity sensor
 *
 * Copyright 2012 Peter Meerwald <pmeerw@pmeerw.net>
 *
 * This file is subject to the terms and conditions of version 2 of
 * the GNU General Public License.  See the file COPYING in the main
 * directory of this archive for more details.
 *
 * IIO driver for si114x (7-bit I2C slave address 0x5a) with sequencer
 * version >= A03
 */

#ifndef __CROS_EC_ALS_SI114X_H
#define __CROS_EC_ALS_SI114X_H

#define SI114X_ADDR                     (0x5a << 1)

#define SI114X_REG_PART_ID		0x00
#define SI114X_SI1141_ID                     0x41
#define SI114X_SI1142_ID                     0x42
#define SI114X_SI1143_ID                     0x43

#define SI114X_NUM_LEDS  (CONFIG_ALS_SI114X - 0x40)

#define SI114X_REG_REV_ID		0x01
#define SI114X_REG_SEQ_ID		0x02
#define SI114X_REG_INT_CFG		0x03
#define SI114X_REG_IRQ_ENABLE		0x04
#define SI114X_REG_IRQ_MODE1		0x05
#define SI114X_REG_IRQ_MODE2		0x06
#define SI114X_REG_HW_KEY		0x07
/* RATE stores a 16 bit value compressed to 8 bit */
/* Not used, the sensor is in force mode */
#define SI114X_REG_MEAS_RATE		0x08


#define SI114X_REG_ALS_RATE		0x09
#define SI114X_REG_PS_RATE		0x0a
#define SI114X_REG_ALS_LOW_TH0		0x0b
#define SI114X_REG_ALS_LOW_TH1		0x0c
#define SI114X_REG_ALS_HI_TH0		0x0d
#define SI114X_REG_ALS_HI_TH1		0x0e
#define SI114X_REG_PS_LED21		0x0f
#define SI114X_REG_PS_LED3		0x10
/*
 * for rev A10 and below TH0 stores a 16 bit value compressed to 8 bit and
 * TH1 is not used; newer revision have the LSB in TH0 and the MSB in TH1
 */
#define SI114X_REG_PS1_TH0		0x11
#define SI114X_REG_PS1_TH1		0x12
#define SI114X_REG_PS2_TH0		0x13
#define SI114X_REG_PS2_TH1		0x11
#define SI114X_REG_PS3_TH0		0x15
#define SI114X_REG_PS3_TH1		0x16
#define SI114X_REG_PARAM_WR		0x17
#define SI114X_REG_COMMAND		0x18
#define SI114X_REG_RESPONSE		0x20
#define SI114X_REG_IRQ_STATUS		0x21
#define SI114X_REG_ALSVIS_DATA0		0x22
#define SI114X_REG_ALSVIS_DATA1		0x23
#define SI114X_REG_ALSIR_DATA0		0x24
#define SI114X_REG_ALSIR_DATA1		0x25
#define SI114X_REG_PS1_DATA0		0x26
#define SI114X_REG_PS1_DATA1		0x27
#define SI114X_REG_PS2_DATA0		0x28
#define SI114X_REG_PS2_DATA1		0x29
#define SI114X_REG_PS3_DATA0		0x2a
#define SI114X_REG_PS3_DATA1		0x2b
#define SI114X_PS_INVERSION(_data) ((1 << 16) / (_data))
#define SI114X_REG_AUX_DATA0		0x2c
#define SI114X_REG_AUX_DATA1		0x2d
#define SI114X_REG_PARAM_RD		0x2e
#define SI114X_REG_CHIP_STAT		0x30

/* helper to figure out PS_LED register / shift per channel */
#define SI114X_PS_LED_REG(ch) \
	(((ch) == 2) ? SI114X_REG_PS_LED3 : SI114X_REG_PS_LED21)
#define SI114X_PS_LED_SHIFT(ch) \
	(((ch) == 1) ? 4 : 0)

/* Parameter offsets */
#define SI114X_PARAM_I2C_ADDR		0x00
#define SI114X_PARAM_CHLIST		0x01
#define SI114X_PARAM_PSLED12_SELECT	0x02
#define SI114X_PARAM_PSLED3_SELECT	0x03
#define SI114X_PARAM_FILTER_EN		0x04
#define SI114X_PARAM_PS_ENCODING	0x05
#define SI114X_PARAM_ALS_ENCODING	0x06
#define SI114X_PARAM_PS1_ADC_MUX	0x07
#define SI114X_PARAM_PS2_ADC_MUX	0x08
#define SI114X_PARAM_PS3_ADC_MUX	0x09
#define SI114X_PARAM_PS_ADC_COUNTER	0x0a
#define SI114X_PARAM_PS_ADC_GAIN	0x0b
#define SI114X_PARAM_PS_ADC_MISC	0x0c
#define SI114X_PARAM_PS_ADC_MISC_HIGH_RANGE       0x20
#define SI114X_PARAM_PS_ADC_MISC_NORMAL_MODE      0x04
#define SI114X_PARAM_ALS_ADC_MUX	0x0d
#define SI114X_PARAM_ALSIR_ADC_MUX	0x0e
#define SI114X_PARAM_AUX_ADC_MUX	0x0f
#define SI114X_PARAM_ALSVIS_ADC_COUNTER	0x10
#define SI114X_PARAM_ALSVIS_ADC_GAIN	0x11
#define SI114X_PARAM_ALSVIS_ADC_MISC	0x12
#define SI114X_PARAM_ALS_HYST		0x16
#define SI114X_PARAM_PS_HYST		0x17
#define SI114X_PARAM_PS_HISTORY		0x18
#define SI114X_PARAM_ALS_HISTORY	0x19
#define SI114X_PARAM_ADC_OFFSET		0x1a
#define SI114X_PARAM_SLEEP_CTRL		0x1b
#define SI114X_PARAM_LED_RECOVERY	0x1c
#define SI114X_PARAM_ALSIR_ADC_COUNTER	0x1d
#define SI114X_PARAM_ALSIR_ADC_GAIN	0x1e
#define SI114X_PARAM_ALSIR_ADC_MISC	0x1f

/* Channel enable masks for CHLIST parameter */
#define SI114X_CHLIST_EN_PS1		0x01
#define SI114X_CHLIST_EN_PS2		0x02
#define SI114X_CHLIST_EN_PS3		0x04
#define SI114X_CHLIST_EN_ALSVIS		0x10
#define SI114X_CHLIST_EN_ALSIR		0x20
#define SI114X_CHLIST_EN_AUX		0x40

/* Signal range mask for ADC_MISC parameter */
#define SI114X_MISC_RANGE		0x20

/* Commands for REG_COMMAND */
#define SI114X_CMD_NOP			0x00
#define SI114X_CMD_RESET		0x01
#define SI114X_CMD_BUSADDR		0x02
#define SI114X_CMD_PS_FORCE		0x05
#define SI114X_CMD_ALS_FORCE		0x06
#define SI114X_CMD_PSALS_FORCE		0x07
#define SI114X_CMD_PS_PAUSE		0x09
#define SI114X_CMD_ALS_PAUSE		0x0a
#define SI114X_CMD_PSALS_PAUSE		0x0b
#define SI114X_CMD_PS_AUTO		0x0d
#define SI114X_CMD_ALS_AUTO		0x0e
#define SI114X_CMD_PSALS_AUTO		0x0f
#define SI114X_CMD_PARAM_QUERY		0x80
#define SI114X_CMD_PARAM_SET		0xa0
#define SI114X_CMD_PARAM_AND		0xc0
#define SI114X_CMD_PARAM_OR		0xe0

/* Interrupt configuration masks for INT_CFG register */
#define SI114X_INT_CFG_OE		0x01 /* enable interrupt */
#define SI114X_INT_CFG_MODE		0x02 /* auto reset interrupt pin */

/* Interrupt enable masks for IRQ_ENABLE register */
#define SI114X_CMD_IE			0x20
#define SI114X_PS3_IE			0x10
#define SI114X_PS2_IE			0x08
#define SI114X_PS1_IE			0x04
#define SI114X_ALS_INT1_IE		0x02
#define SI114X_ALS_INT0_IE		0x01
#define SI114X_ALS_INT_FLAG \
	(SI114X_ALS_INT1_IE | SI114X_ALS_INT0_IE)
#define SI114X_PS_INT_FLAG \
	(SI114X_PS3_IE | SI114X_PS2_IE | SI114X_PS1_IE)


/* Interrupt mode masks for IRQ_MODE1 register */
#define SI114X_PS2_IM_GREATER		0xc0
#define SI114X_PS2_IM_CROSS		0x40
#define SI114X_PS1_IM_GREATER		0x30
#define SI114X_PS1_IM_CROSS		0x10

/* Interrupt mode masks for IRQ_MODE2 register */
#define SI114X_CMD_IM_ERROR		0x04
#define SI114X_PS3_IM_GREATER		0x03
#define SI114X_PS3_IM_CROSS		0x01

/* Measurement rate settings */
#define SI114X_MEAS_RATE_FORCED		0x00
#define SI114X_MEAS_RATE_10MS		0x84
#define SI114X_MEAS_RATE_20MS		0x94
#define SI114X_MEAS_RATE_100MS		0xb9
#define SI114X_MEAS_RATE_496MS		0xdf
#define SI114X_MEAS_RATE_1984MS		0xff

/* ALS rate settings relative to measurement rate */
#define SI114X_ALS_RATE_OFF		0x00
#define SI114X_ALS_RATE_1X		0x08
#define SI114X_ALS_RATE_10X		0x32
#define SI114X_ALS_RATE_100X		0x69

/* PS rate settings relative to measurement rate */
#define SI114X_PS_RATE_OFF		0x00
#define SI114X_PS_RATE_1X		0x08
#define SI114X_PS_RATE_10X		0x32
#define SI114X_PS_RATE_100X		0x69

/* Sequencer revision from SEQ_ID */
#define SI114X_SEQ_REV_A01		0x01
#define SI114X_SEQ_REV_A02		0x02
#define SI114X_SEQ_REV_A03		0x03
#define SI114X_SEQ_REV_A10		0x08
#define SI114X_SEQ_REV_A11		0x09

/* Proximity sensor finds an object within 5 cm, disable light sensor */
#define SI114X_COVERED_THRESHOLD        5
#define SI114X_OVERFLOW                 0xffff

/* Time to wait before re-initializing the device if access is denied */
#define SI114X_DENIED_THRESHOLD		(10 * SECOND)

/* Delay used for deferred callback when polling is enabled */
#define SI114x_POLLING_DELAY (8 * MSEC)

/* Min and Max sampling frequency in mHz */
#define SI114X_PROX_MIN_FREQ            504
#define SI114X_PROX_MAX_FREQ            50000
#define SI114X_LIGHT_MIN_FREQ           504
#define SI114X_LIGHT_MAX_FREQ           50000
#if (CONFIG_EC_MAX_SENSOR_FREQ_MILLIHZ <= SI114X_PROX_MAX_FREQ)
#error "EC too slow for light sensor"
#endif

extern const struct accelgyro_drv si114x_drv;

enum si114x_state {
	SI114X_NOT_READY,
	SI114X_IDLE,
	SI114X_ALS_IN_PROGRESS,
	SI114X_ALS_IN_PROGRESS_PS_PENDING,
	SI114X_PS_IN_PROGRESS,
	SI114X_PS_IN_PROGRESS_ALS_PENDING,
};

/**
 * struct si114x_data - si114x chip state data
 * @client:	I2C client
 **/
struct si114x_typed_data_t {
	uint8_t base_data_reg;
	uint8_t irq_flags;
	/* requested frequency, in mHz */
	int rate;
	/* the coef is scale.uscale */
	int16_t scale;
	uint16_t uscale;
	int16_t offset;
};

struct si114x_drv_data_t {
	enum si114x_state state;
	uint8_t covered;
	struct si114x_typed_data_t type_data[2];
};

#define SI114X_GET_DATA(_s) \
	((struct si114x_drv_data_t *)(_s)->drv_data)

#define SI114X_GET_TYPED_DATA(_s) \
	(&SI114X_GET_DATA(_s)->type_data[(_s)->type - MOTIONSENSE_TYPE_PROX])

void si114x_interrupt(enum gpio_signal signal);

#endif	/* __CROS_EC_ALS_SI114X_H */