blob: bfecc60f40df233deaedc71230d379276a4da64c [file] [log] [blame]
Vadim Bendebury71558f52015-03-09 15:50:56 -07001/*
2 * Copyright (C) 2015 Google, Inc.
3 *
4 * This software is licensed under the terms of the GNU General Public
5 * License version 2, as published by the Free Software Foundation, and
6 * may be copied, distributed, and modified under those terms.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
12 */
13
14/*
15 * This is a driver for the Whirlwind LED ring, which is equipped with two LED
16 * microcontrollers TI LP55231 (http://www.ti.com/product/lp55231), each of
17 * them driving three multicolor LEDs.
18 *
19 * The only connection between the ring and the main board is an i2c bus.
20 *
21 * This driver imitates a depthcharge display device. On initialization the
22 * driver sets up the controllers to prepare them to accept programs to run.
23 *
24 * When a certain vboot state needs to be indicated, the program for that
25 * state is loaded into the controllers, resulting in the state appropriate
26 * LED behavior.
27 */
28
29#include <console/console.h>
Vadim Bendebury507a0cb2015-03-16 14:12:40 -070030#include <delay.h>
Vadim Bendebury71558f52015-03-09 15:50:56 -070031#include <device/i2c.h>
32#include <string.h>
33
Vadim Bendebury5fa5f992015-03-17 15:15:42 -070034#include "drivers/i2c/ww_ring/ww_ring_programs.h"
Vadim Bendebury71558f52015-03-09 15:50:56 -070035
36/* I2c address of the first of the controllers, the rest are contiguous. */
37#define WW_RING_BASE_ADDR 0x32
38
39/* Key lp55231 registers. */
40#define LP55231_ENGCTRL1_REG 0x00
41#define LP55231_ENGCTRL2_REG 0x01
42#define LP55231_D1_CRT_CTRL_REG 0x26
43#define LP55231_MISC_REG 0x36
Vadim Bendebury507a0cb2015-03-16 14:12:40 -070044#define LP55231_VARIABLE_REG 0x3c
Vadim Bendebury71558f52015-03-09 15:50:56 -070045#define LP55231_RESET_REG 0x3d
46#define LP55231_ENG1_PROG_START 0x4c
47#define LP55231_PROG_PAGE_REG 0x4f
48#define LP55231_PROG_BASE_REG 0x50
49
50/* LP55231_D1_CRT_CTRL_REG, default value, applies to all nine of them */
51#define LP55231_CRT_CTRL_DEFAULT 0xaf
52
53/* LP55231_ENGCTRL1_REG fields */
54#define LP55231_ENGCTRL1_CHIP_EN 0x40
55#define LP55231_ENGCTRL1_ALL_ENG_GO 0x2a
56
Vadim Bendebury507a0cb2015-03-16 14:12:40 -070057/* LP55231_ENGCTRL2_REG fields. */
58#define LP55231_ENGCTRL2_ALL_DISABLE 0
59#define LP55231_ENGCTRL2_ALL_LOAD 0x15
60#define LP55231_ENGCTRL2_ALL_RUN 0x2a
61
Vadim Bendebury71558f52015-03-09 15:50:56 -070062/* LP55231_MISC_REG fields. */
63#define LP55231_MISC_AUTOINCR (1 << 6)
64#define LP55231_MISC_PUMP_1X (1 << 3)
65#define LP55231_MISC_INT_CLK (3 << 0)
66
Vadim Bendebury507a0cb2015-03-16 14:12:40 -070067/*
68 * LP55231_VARIABLE_REG cookie value. It indicates to depthcharge that the
69 * ring has been initialized by coreboot.
70 */
71#define LP55231_VARIABLE_COOKIE 0xb4
72
Vadim Bendebury71558f52015-03-09 15:50:56 -070073/* Goes into LP55231_RESET_REG to reset the chip. */
74#define LP55231_RESET_VALUE 0xff
75
76/*
77 * The controller has 192 bytes of SRAM for code/data, availabe as six 32 byte
78 * pages.
79 */
80#define LP55231_PROG_PAGE_SIZE 32
81#define LP55231_PROG_PAGES 6
82#define LP55231_MAX_PROG_SIZE (LP55231_PROG_PAGE_SIZE * LP55231_PROG_PAGES)
83
Vadim Bendebury71558f52015-03-09 15:50:56 -070084/*
85 * Structure to cache data relevant to accessing one controller. I2c interface
86 * to use, device address on the i2c bus and a data buffer for write
87 * transactions. The most bytes sent at a time is the register address plus
88 * the program page size.
89 */
90typedef struct {
91 unsigned i2c_bus;
92 uint8_t dev_addr;
93 uint8_t data_buffer[LP55231_PROG_PAGE_SIZE + 1];
94} TiLp55231;
95
Vadim Bendebury71558f52015-03-09 15:50:56 -070096static void ww_ring_init(unsigned i2c_bus);
97
Vadim Bendebury71558f52015-03-09 15:50:56 -070098/* Controller descriptors. */
99static TiLp55231 lp55231s[WW_RING_NUM_LED_CONTROLLERS];
100
101/*
102 * i2c transfer function for the driver. To keep things simple, the function
103 * repeats the transfer, if the first attempt fails. This is OK with the
104 * controller and makes it easier to handle errors.
105 *
106 * Note that the reset register accesses are expected to fail on writes, but
107 * due to a bug in the ipq806x i2c controller, the error is reported on the
108 * following read attempt.
109 *
110 * To work around this the driver writes and then reads the reset register,
111 * the transfer function ignores errors when accessing the reset register.
112 */
113
114static int ledc_transfer(TiLp55231 *ledc, struct i2c_seg *segs,
115 int seg_count, int reset)
116{
117 int rv, max_attempts = 2;
118
119 while (max_attempts--) {
120 rv = i2c_transfer(ledc->i2c_bus, segs, seg_count);
121
122 /* Accessing reset regsiter is expected to fail. */
123 if (!rv || reset)
124 break;
125 }
126
127 if (rv) {
128 if (!reset)
129 printk(BIOS_WARNING,
130 "%s: dev %#x, reg %#x, %s transaction error.\n",
131 __func__, segs->chip, segs->buf[0],
132 seg_count == 1 ? "write" : "read");
133 else
134 rv = 0;
135 }
136
137 return rv;
138}
139
140/*
141 * The controller is programmed to autoincrement on writes, so up to page size
142 * bytes can be transmitted in one write transaction.
143 */
144static int ledc_write(TiLp55231 *ledc, uint8_t start_addr,
145 const uint8_t *data, unsigned count)
146{
147 struct i2c_seg seg;
148
149 if (count > (sizeof(ledc->data_buffer) - 1)) {
150 printk(BIOS_WARNING, "%s: transfer size too large (%d bytes)\n",
151 __func__, count);
152 return -1;
153 }
154
155 memcpy(ledc->data_buffer + 1, data, count);
156 ledc->data_buffer[0] = start_addr;
157
158 seg.read = 0;
159 seg.chip = ledc->dev_addr;
160 seg.buf = ledc->data_buffer;
161 seg.len = count + 1;
162
163 return ledc_transfer(ledc, &seg, 1, start_addr == LP55231_RESET_REG);
164}
165
166/* To keep things simple, read is limited to one byte at a time. */
167static int ledc_read(TiLp55231 *ledc, uint8_t addr, uint8_t *data)
168{
169 struct i2c_seg seg[2];
170
171 seg[0].read = 0;
172 seg[0].chip = ledc->dev_addr;
173 seg[0].buf = &addr;
174 seg[0].len = 1;
175
176 seg[1].read = 1;
177 seg[1].chip = ledc->dev_addr;
178 seg[1].buf = data;
179 seg[1].len = 1;
180
181 return ledc_transfer(ledc, seg, ARRAY_SIZE(seg),
182 addr == LP55231_RESET_REG);
183}
184
185/*
Vadim Bendebury507a0cb2015-03-16 14:12:40 -0700186 * Reset transaction is expected to result in a failing i2c command. But even
187 * before trying it, read the reset register, which is supposed to always
188 * return 0. If this fails - there is no lp55231 at this address.
189 *
190 * Return 0 on success, -1 on failure to detect controller.
Vadim Bendebury71558f52015-03-09 15:50:56 -0700191 */
Vadim Bendebury507a0cb2015-03-16 14:12:40 -0700192static int ledc_reset(TiLp55231 *ledc)
Vadim Bendebury71558f52015-03-09 15:50:56 -0700193{
194 uint8_t data;
195
Vadim Bendebury507a0cb2015-03-16 14:12:40 -0700196 data = ~0;
197 ledc_read(ledc, LP55231_RESET_REG, &data);
198 if (data) {
199 printk(BIOS_WARNING,
200 "WW_RING: no controller found at address %#2.2x\n",
201 ledc->dev_addr);
202 return -1;
203 }
204
Vadim Bendebury71558f52015-03-09 15:50:56 -0700205 data = LP55231_RESET_VALUE;
206 ledc_write(ledc, LP55231_RESET_REG, &data, 1);
207
208 /*
209 * This read is not necessary for the chip reset, but is required to
210 * work around the i2c driver bug where the missing ACK on the last
211 * byte of the write transaction is ignored, but the next transaction
212 * fails.
213 */
214 ledc_read(ledc, LP55231_RESET_REG, &data);
Vadim Bendebury507a0cb2015-03-16 14:12:40 -0700215 return 0;
Vadim Bendebury71558f52015-03-09 15:50:56 -0700216}
217
218/*
219 * Write a program into the internal lp55231 memory. Split write transactions
220 * into sections fitting into memory pages.
221 */
222static void ledc_write_program(TiLp55231 *ledc, uint8_t load_addr,
223 const uint8_t *program, unsigned count)
224{
225 uint8_t page_num = load_addr / LP55231_PROG_PAGE_SIZE;
226 unsigned page_offs = load_addr % LP55231_PROG_PAGE_SIZE;
227
228 if ((load_addr + count) > LP55231_MAX_PROG_SIZE) {
229 printk(BIOS_WARNING,
230 "%s: program of size %#x does not fit at addr %#x\n",
231 __func__, count, load_addr);
232 return;
233 }
234
235 while (count) {
236 unsigned segment_size = LP55231_PROG_PAGE_SIZE - page_offs;
237
238 if (segment_size > count)
239 segment_size = count;
240
241 ledc_write(ledc, LP55231_PROG_PAGE_REG, &page_num, 1);
242 ledc_write(ledc, LP55231_PROG_BASE_REG + page_offs,
243 program, segment_size);
244
245 count -= segment_size;
Vadim Bendebury507a0cb2015-03-16 14:12:40 -0700246 program += segment_size;
Vadim Bendebury71558f52015-03-09 15:50:56 -0700247 page_offs = 0;
248 page_num++;
249 }
250}
251
Vadim Bendebury507a0cb2015-03-16 14:12:40 -0700252static void ledc_write_engctrl2(TiLp55231 *ledc, uint8_t value)
253{
254 ledc_write(ledc, LP55231_ENGCTRL2_REG, &value, 1);
255 udelay(1500);
256}
257
Vadim Bendebury71558f52015-03-09 15:50:56 -0700258/* Run an lp55231 program on a controller. */
259static void ledc_run_program(TiLp55231 *ledc,
260 const TiLp55231Program *program_desc)
261{
Vadim Bendebury71558f52015-03-09 15:50:56 -0700262 int i;
Vadim Bendebury507a0cb2015-03-16 14:12:40 -0700263 uint8_t data;
Vadim Bendebury71558f52015-03-09 15:50:56 -0700264
Vadim Bendebury507a0cb2015-03-16 14:12:40 -0700265 /* All engines on hold. */
266 data = LP55231_ENGCTRL1_CHIP_EN;
267 ledc_write(ledc, LP55231_ENGCTRL1_REG, &data, 1);
268
269 ledc_write_engctrl2(ledc, LP55231_ENGCTRL2_ALL_DISABLE);
270 ledc_write_engctrl2(ledc, LP55231_ENGCTRL2_ALL_LOAD);
271
Vadim Bendebury71558f52015-03-09 15:50:56 -0700272 ledc_write_program(ledc, program_desc->load_addr,
273 program_desc->program_text,
274 program_desc->program_size);
275
276 for (i = 0; i < sizeof(program_desc->engine_start_addr); i++)
277 ledc_write(ledc, LP55231_ENG1_PROG_START + i,
278 program_desc->engine_start_addr + i, 1);
279
Vadim Bendebury507a0cb2015-03-16 14:12:40 -0700280 data = LP55231_ENGCTRL1_CHIP_EN | LP55231_ENGCTRL1_ALL_ENG_GO;
281 ledc_write(ledc, LP55231_ENGCTRL1_REG, &data, 1);
282 ledc_write_engctrl2(ledc, LP55231_ENGCTRL2_ALL_RUN);
Vadim Bendebury71558f52015-03-09 15:50:56 -0700283}
284
285/*
286 * Initialize a controller to a state were it is ready to accept programs, and
287 * try to confirm that we are in fact talking to a lp55231
288 */
289static int ledc_init_validate(TiLp55231 *ledc)
290{
Vadim Bendebury71558f52015-03-09 15:50:56 -0700291 uint8_t data;
292 int i;
293
Vadim Bendebury507a0cb2015-03-16 14:12:40 -0700294 if (ledc_reset(ledc))
295 return -1;
Vadim Bendebury71558f52015-03-09 15:50:56 -0700296
Vadim Bendebury507a0cb2015-03-16 14:12:40 -0700297 /* Enable the chip, keep engines in hold state. */
298 data = LP55231_ENGCTRL1_CHIP_EN;
299 ledc_write(ledc, LP55231_ENGCTRL1_REG, &data, 1);
Vadim Bendebury71558f52015-03-09 15:50:56 -0700300
301 /*
302 * Internal clock, 3.3V output (pump 1x), autoincrement on multibyte
303 * writes.
304 */
305 data = LP55231_MISC_AUTOINCR |
306 LP55231_MISC_PUMP_1X | LP55231_MISC_INT_CLK;
307 ledc_write(ledc, LP55231_MISC_REG, &data, 1);
308
309 /*
310 * All nine current control registers are supposed to return the same
311 * value at reset.
312 */
313 for (i = 0; i < 9; i++) {
Vadim Bendebury71558f52015-03-09 15:50:56 -0700314 ledc_read(ledc, LP55231_D1_CRT_CTRL_REG + i, &data);
315 if (data != LP55231_CRT_CTRL_DEFAULT) {
316 printk(BIOS_WARNING,
317 "%s: read %#2.2x from register %#x\n", __func__,
318 data, LP55231_D1_CRT_CTRL_REG + i);
319 return -1;
320 }
321 }
322
Vadim Bendebury507a0cb2015-03-16 14:12:40 -0700323 /*
324 * Signal Depthcharge that the controller has been initiazed by
325 * coreboot.
326 */
327 data = LP55231_VARIABLE_COOKIE;
328 ledc_write(ledc, LP55231_VARIABLE_REG, &data, 1);
329
Vadim Bendebury71558f52015-03-09 15:50:56 -0700330 return 0;
331}
332
333/*
334 * Find a program matching screen type, and run it on both controllers, if
335 * found.
336 */
Vadim Bendebury4e0de322015-03-17 15:37:54 -0700337int ww_ring_display_pattern(unsigned i2c_bus, enum display_pattern pattern)
Vadim Bendebury71558f52015-03-09 15:50:56 -0700338{
Vadim Bendebury71558f52015-03-09 15:50:56 -0700339 static int initted;
Vadim Bendebury5fa5f992015-03-17 15:15:42 -0700340 const WwRingStateProg *wwr_prog;
Vadim Bendebury71558f52015-03-09 15:50:56 -0700341
342 if (!initted) {
343 ww_ring_init(i2c_bus);
344 initted = 1;
345 }
346
Vadim Bendebury5fa5f992015-03-17 15:15:42 -0700347 /* Last entry does not have any actual programs defined. */
348 for (wwr_prog = wwr_state_programs; wwr_prog->programs[0]; wwr_prog++)
349 if (wwr_prog->led_pattern == pattern) {
Vadim Bendebury71558f52015-03-09 15:50:56 -0700350 int j;
Vadim Bendebury507a0cb2015-03-16 14:12:40 -0700351
Vadim Bendebury420fb5e2015-03-19 10:14:13 -0700352 /*
353 * First stop all running programs to avoid
354 * inerference between the controllers.
355 */
356 for (j = 0; j < WW_RING_NUM_LED_CONTROLLERS; j++) {
357 if (!lp55231s[j].dev_addr)
358 continue;
359 ledc_write_engctrl2
360 (lp55231s + j,
361 LP55231_ENGCTRL2_ALL_DISABLE);
362 }
363
Vadim Bendebury507a0cb2015-03-16 14:12:40 -0700364 for (j = 0; j < WW_RING_NUM_LED_CONTROLLERS; j++) {
365 if (!lp55231s[j].dev_addr)
366 continue;
Vadim Bendebury71558f52015-03-09 15:50:56 -0700367 ledc_run_program(lp55231s + j,
Vadim Bendebury5fa5f992015-03-17 15:15:42 -0700368 wwr_prog->programs[j]);
Vadim Bendebury507a0cb2015-03-16 14:12:40 -0700369 }
Vadim Bendebury71558f52015-03-09 15:50:56 -0700370 return 0;
371 }
372
Vadim Bendebury4e0de322015-03-17 15:37:54 -0700373 printk(BIOS_WARNING, "%s: did not find program for pattern %d\n",
374 __func__, pattern);
Vadim Bendebury71558f52015-03-09 15:50:56 -0700375
376 return -1;
377}
378
379
380#define LP55231_I2C_BASE_ADDR 0x32
381
382static void ww_ring_init(unsigned i2c_bus)
383{
384 TiLp55231 *ledc;
385 int i, count = 0;
386
387 for (i = 0, ledc = lp55231s;
388 i < WW_RING_NUM_LED_CONTROLLERS;
389 i++, ledc++) {
390
391 ledc->i2c_bus = i2c_bus;
392 ledc->dev_addr = LP55231_I2C_BASE_ADDR + i;
393
394 if (!ledc_init_validate(ledc))
395 count++;
Vadim Bendebury507a0cb2015-03-16 14:12:40 -0700396 else
397 ledc->dev_addr = 0; /* Mark disabled. */
Vadim Bendebury71558f52015-03-09 15:50:56 -0700398 }
399
400 printk(BIOS_INFO, "WW_RING: initialized %d out of %d\n", count, i);
Vadim Bendebury507a0cb2015-03-16 14:12:40 -0700401 if (count != i) {
402 if (count)
403 printk(BIOS_WARNING,
404 "WW_RING: will keep going anyway\n");
405 else
406 printk(BIOS_WARNING,
407 "WW_RING: LED ring not present\n");
408 }
Vadim Bendebury71558f52015-03-09 15:50:56 -0700409}