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_common.h>
18 #include <soc/pmic_wrap_common.h>
20 /* For CBI un-provisioned/corrupted Flapjack board. */
21 #define FLAPJACK_UNDEF_SKU_ID 0
26 LCM_ID_CHANNEL
= 2, /* ID of LCD Module on schematics. */
31 static const int ram_voltages
[ADC_LEVELS
] = {
32 /* ID : Voltage (unit: uV) */
47 static const int lcm_voltages
[ADC_LEVELS
] = {
48 /* ID : Voltage (unit: uV) */
63 static const int *adc_voltages
[] = {
64 [LCM_ID_CHANNEL
] = lcm_voltages
,
65 [RAM_ID_CHANNEL
] = ram_voltages
,
66 [SKU_ID_CHANNEL
] = ram_voltages
, /* SKU ID is sharing RAM voltages. */
69 static uint32_t get_adc_index(unsigned int channel
)
71 int value
= auxadc_get_voltage_uv(channel
);
73 assert(channel
< ARRAY_SIZE(adc_voltages
));
74 const int *voltages
= adc_voltages
[channel
];
77 /* Find the closest voltage */
79 for (id
= 0; id
< ADC_LEVELS
- 1; id
++)
80 if (value
< (voltages
[id
] + voltages
[id
+ 1]) / 2)
82 printk(BIOS_DEBUG
, "ADC[%d]: Raw value=%d ID=%d\n", channel
, value
, id
);
86 static uint8_t eeprom_random_read(uint8_t bus
, uint8_t slave
, uint16_t offset
,
87 uint8_t *data
, uint16_t len
)
89 struct i2c_msg seg
[2];
92 address
[0] = offset
>> 8;
93 address
[1] = offset
& 0xff;
98 seg
[0].len
= sizeof(address
);
99 seg
[1].flags
= I2C_M_RD
;
100 seg
[1].slave
= slave
;
104 return i2c_transfer(bus
, seg
, ARRAY_SIZE(seg
));
107 /* Regulator for world facing camera. */
108 #define PMIC_LDO_VCAMIO_CON0 0x1cb0
110 #define CROS_CAMERA_INFO_OFFSET 0x1f80
111 #define MT8183_FORMAT 0x8183
112 #define KODAMA_PID 0x00c7
114 /* Returns the ID for world facing camera. */
115 static uint8_t wfc_id(void)
117 if (!CONFIG(BOARD_GOOGLE_KODAMA
))
122 uint8_t dev_addr
= 0x50; /* at24c32/64 device address */
124 struct cros_camera_info data
= {0};
126 const uint16_t sensor_pids
[] = {
127 [0] = 0x5965, /* OV5965 */
128 [1] = 0x5035, /* GC5035 */
131 mtk_i2c_bus_init(bus
);
133 /* Turn on camera sensor EEPROM */
134 pwrap_write(PMIC_LDO_VCAMIO_CON0
, 0x1);
137 ret
= eeprom_random_read(bus
, dev_addr
, CROS_CAMERA_INFO_OFFSET
,
138 (uint8_t *)&data
, sizeof(data
));
139 pwrap_write(PMIC_LDO_VCAMIO_CON0
, 0x0);
143 "Failed to read from EEPROM; using default WFC id 0\n");
147 if (check_cros_camera_info(&data
)) {
149 "Failed to check camera info; using default WFC id 0\n");
153 if (data
.data_format
!= MT8183_FORMAT
) {
154 printk(BIOS_ERR
, "Incompatible camera format: %#04x\n",
158 if (data
.module_pid
!= KODAMA_PID
) {
159 printk(BIOS_ERR
, "Incompatible module pid: %#04x\n",
164 printk(BIOS_DEBUG
, "Camera sensor pid: %#04x\n", data
.sensor_pid
);
166 for (i
= 0; i
< ARRAY_SIZE(sensor_pids
); i
++) {
167 if (data
.sensor_pid
== sensor_pids
[i
]) {
168 printk(BIOS_INFO
, "Detected WFC id: %d\n", i
);
173 printk(BIOS_WARNING
, "Unknown WFC id; using default id 0\n");
177 /* Returns the ID for LCD module (type of panel). */
178 static uint8_t lcm_id(void)
180 /* LCM is unused on Jacuzzi followers. */
181 if (CONFIG(BOARD_GOOGLE_JACUZZI_COMMON
))
182 return CONFIG_BOARD_OVERRIDE_LCM_ID
;
184 return get_adc_index(LCM_ID_CHANNEL
);
187 uint32_t sku_id(void)
189 static uint32_t cached_sku_id
= BOARD_ID_INIT
;
191 if (cached_sku_id
!= BOARD_ID_INIT
)
192 return cached_sku_id
;
194 /* On Flapjack, getting the SKU via CBI. */
195 if (CONFIG(BOARD_GOOGLE_FLAPJACK
)) {
196 if (google_chromeec_cbi_get_sku_id(&cached_sku_id
))
197 cached_sku_id
= FLAPJACK_UNDEF_SKU_ID
;
198 return cached_sku_id
;
201 /* Quirk for Kukui: All Rev1/Sku0 had incorrectly set SKU_ID=1. */
202 if (CONFIG(BOARD_GOOGLE_KUKUI
)) {
203 if (board_id() == 1) {
205 return cached_sku_id
;
210 * The SKU (later used for device tree matching) is combined from:
211 * World facing camera (WFC) ID.
212 * ADC2[4bit/H] = straps on LCD module (type of panel).
213 * ADC4[4bit/L] = SKU ID from board straps.
215 cached_sku_id
= (wfc_id() << 8 |
217 get_adc_index(SKU_ID_CHANNEL
));
219 return cached_sku_id
;
222 uint32_t ram_code(void)
224 static uint32_t cached_ram_code
= BOARD_ID_INIT
;
226 if (cached_ram_code
== BOARD_ID_INIT
) {
227 cached_ram_code
= get_adc_index(RAM_ID_CHANNEL
);
228 /* Model-specific offset - see sdram_configs.c for details. */
229 cached_ram_code
+= CONFIG_BOARD_SDRAM_TABLE_OFFSET
;
231 return cached_ram_code
;