1 /* SPDX-License-Identifier: GPL-2.0-only */
4 * The boardid.c should provide board_id, sku_id, and ram_code.
5 * board_id is provided by ec/google/chromeec/ec_boardid.c.
6 * sku_id and ram_code are defined in this file.
11 #include <console/console.h>
13 #include <device/i2c_simple.h>
14 #include <drivers/camera/cros_camera.h>
15 #include <ec/google/chromeec/ec.h>
16 #include <soc/auxadc.h>
18 #include <soc/pmic_wrap_common.h>
21 /* For CBI un-provisioned/corrupted Flapjack board. */
22 #define FLAPJACK_UNDEF_SKU_ID 0
27 LCM_ID_CHANNEL
= 2, /* ID of LCD Module on schematics. */
32 static const int ram_voltages
[ADC_LEVELS
] = {
33 /* ID : Voltage (unit: uV) */
48 static const int lcm_voltages
[ADC_LEVELS
] = {
49 /* ID : Voltage (unit: uV) */
64 static const int *adc_voltages
[] = {
65 [LCM_ID_CHANNEL
] = lcm_voltages
,
66 [RAM_ID_CHANNEL
] = ram_voltages
,
67 [SKU_ID_CHANNEL
] = ram_voltages
, /* SKU ID is sharing RAM voltages. */
70 static uint32_t get_adc_index(unsigned int channel
)
72 int value
= auxadc_get_voltage(channel
);
74 assert(channel
< ARRAY_SIZE(adc_voltages
));
75 const int *voltages
= adc_voltages
[channel
];
78 /* Find the closest voltage */
80 for (id
= 0; id
< ADC_LEVELS
- 1; id
++)
81 if (value
< (voltages
[id
] + voltages
[id
+ 1]) / 2)
83 printk(BIOS_DEBUG
, "ADC[%d]: Raw value=%d ID=%d\n", channel
, value
, id
);
87 static uint8_t eeprom_random_read(uint8_t bus
, uint8_t slave
, uint16_t offset
,
88 uint8_t *data
, uint16_t len
)
90 struct i2c_msg seg
[2];
93 address
[0] = offset
>> 8;
94 address
[1] = offset
& 0xff;
99 seg
[0].len
= sizeof(address
);
100 seg
[1].flags
= I2C_M_RD
;
101 seg
[1].slave
= slave
;
105 return i2c_transfer(bus
, seg
, ARRAY_SIZE(seg
));
108 /* Regulator for world facing camera. */
109 #define PMIC_LDO_VCAMIO_CON0 0x1cb0
111 #define CROS_CAMERA_INFO_OFFSET 0x1f80
112 #define MT8183_FORMAT 0x8183
113 #define KODAMA_PID 0x00c7
115 /* Returns the ID for world facing camera. */
116 static uint8_t wfc_id(void)
118 if (!CONFIG(BOARD_GOOGLE_KODAMA
))
123 uint8_t dev_addr
= 0x50; /* at24c32/64 device address */
125 struct cros_camera_info data
= {0};
127 const uint16_t sensor_pids
[] = {
128 [0] = 0x5965, /* OV5965 */
129 [1] = 0x5035, /* GC5035 */
132 mtk_i2c_bus_init(bus
);
134 /* Turn on camera sensor EEPROM */
135 pwrap_write(PMIC_LDO_VCAMIO_CON0
, 0x1);
138 ret
= eeprom_random_read(bus
, dev_addr
, CROS_CAMERA_INFO_OFFSET
,
139 (uint8_t *)&data
, sizeof(data
));
140 pwrap_write(PMIC_LDO_VCAMIO_CON0
, 0x0);
144 "Failed to read from EEPROM; using default WFC id 0\n");
148 if (check_cros_camera_info(&data
)) {
150 "Failed to check camera info; using default WFC id 0\n");
154 if (data
.data_format
!= MT8183_FORMAT
) {
155 printk(BIOS_ERR
, "Incompatible camera format: %#04x\n",
159 if (data
.module_pid
!= KODAMA_PID
) {
160 printk(BIOS_ERR
, "Incompatible module pid: %#04x\n",
165 printk(BIOS_DEBUG
, "Camera sensor pid: %#04x\n", data
.sensor_pid
);
167 for (i
= 0; i
< ARRAY_SIZE(sensor_pids
); i
++) {
168 if (data
.sensor_pid
== sensor_pids
[i
]) {
169 printk(BIOS_INFO
, "Detected WFC id: %d\n", i
);
174 printk(BIOS_WARNING
, "Unknown WFC id; using default id 0\n");
178 /* Returns the ID for LCD module (type of panel). */
179 static uint8_t lcm_id(void)
181 /* LCM is unused on Jacuzzi followers. */
182 if (CONFIG(BOARD_GOOGLE_JACUZZI_COMMON
))
183 return CONFIG_BOARD_OVERRIDE_LCM_ID
;
185 return get_adc_index(LCM_ID_CHANNEL
);
188 uint32_t sku_id(void)
190 static uint32_t cached_sku_id
= BOARD_ID_INIT
;
192 if (cached_sku_id
!= BOARD_ID_INIT
)
193 return cached_sku_id
;
195 /* On Flapjack, getting the SKU via CBI. */
196 if (CONFIG(BOARD_GOOGLE_FLAPJACK
)) {
197 if (google_chromeec_cbi_get_sku_id(&cached_sku_id
))
198 cached_sku_id
= FLAPJACK_UNDEF_SKU_ID
;
199 return cached_sku_id
;
202 /* Quirk for Kukui: All Rev1/Sku0 had incorrectly set SKU_ID=1. */
203 if (CONFIG(BOARD_GOOGLE_KUKUI
)) {
204 if (board_id() == 1) {
206 return cached_sku_id
;
211 * The SKU (later used for device tree matching) is combined from:
212 * World facing camera (WFC) ID.
213 * ADC2[4bit/H] = straps on LCD module (type of panel).
214 * ADC4[4bit/L] = SKU ID from board straps.
216 cached_sku_id
= (wfc_id() << 8 |
218 get_adc_index(SKU_ID_CHANNEL
));
220 return cached_sku_id
;
223 uint32_t ram_code(void)
225 static uint32_t cached_ram_code
= BOARD_ID_INIT
;
227 if (cached_ram_code
== BOARD_ID_INIT
) {
228 cached_ram_code
= get_adc_index(RAM_ID_CHANNEL
);
229 /* Model-specific offset - see sdram_configs.c for details. */
230 cached_ram_code
+= CONFIG_BOARD_SDRAM_TABLE_OFFSET
;
232 return cached_ram_code
;