xref: /rk3399_rockchip-uboot/drivers/video/s6e63d6.c (revision 326ea986ac150acdc7656d57fca647db80b50158)
1689551c5SGuennadi Liakhovetski /*
2689551c5SGuennadi Liakhovetski  * Copyright (C) 2009
3689551c5SGuennadi Liakhovetski  * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
4689551c5SGuennadi Liakhovetski  *
5*1a459660SWolfgang Denk  * SPDX-License-Identifier:	GPL-2.0+
6689551c5SGuennadi Liakhovetski  */
7689551c5SGuennadi Liakhovetski #include <common.h>
8689551c5SGuennadi Liakhovetski #include <spi.h>
9689551c5SGuennadi Liakhovetski #include <s6e63d6.h>
10689551c5SGuennadi Liakhovetski 
11689551c5SGuennadi Liakhovetski /*
12689551c5SGuennadi Liakhovetski  * Each transfer is performed as:
13689551c5SGuennadi Liakhovetski  * 1. chip-select active
14689551c5SGuennadi Liakhovetski  * 2. send 8-bit start code
15689551c5SGuennadi Liakhovetski  * 3. send 16-bit data
16689551c5SGuennadi Liakhovetski  * 4. chip-select inactive
17689551c5SGuennadi Liakhovetski  */
send_word(struct s6e63d6 * data,u8 rs,u16 word)18689551c5SGuennadi Liakhovetski static int send_word(struct s6e63d6 *data, u8 rs, u16 word)
19689551c5SGuennadi Liakhovetski {
20689551c5SGuennadi Liakhovetski 	/*
21689551c5SGuennadi Liakhovetski 	 * The start byte looks like (binary):
22689551c5SGuennadi Liakhovetski 	 * 01110<ID><RS><R/W>
23689551c5SGuennadi Liakhovetski 	 * RS is 0 for index or 1 for data, and R/W is 0 for write.
24689551c5SGuennadi Liakhovetski 	 */
25689551c5SGuennadi Liakhovetski 	u32 buf8 = 0x70 | data->id | (rs & 2);
26689551c5SGuennadi Liakhovetski 	u32 buf16 = cpu_to_le16(word);
27689551c5SGuennadi Liakhovetski 	u32 buf_in;
28689551c5SGuennadi Liakhovetski 	int err;
29689551c5SGuennadi Liakhovetski 
30689551c5SGuennadi Liakhovetski 	err = spi_xfer(data->slave, 8, &buf8, &buf_in, SPI_XFER_BEGIN);
31689551c5SGuennadi Liakhovetski 	if (err)
32689551c5SGuennadi Liakhovetski 		return err;
33689551c5SGuennadi Liakhovetski 
34689551c5SGuennadi Liakhovetski 	return spi_xfer(data->slave, 16, &buf16, &buf_in, SPI_XFER_END);
35689551c5SGuennadi Liakhovetski }
36689551c5SGuennadi Liakhovetski 
37689551c5SGuennadi Liakhovetski /* Index and param differ in Register Select bit */
s6e63d6_index(struct s6e63d6 * data,u8 idx)38689551c5SGuennadi Liakhovetski int s6e63d6_index(struct s6e63d6 *data, u8 idx)
39689551c5SGuennadi Liakhovetski {
40689551c5SGuennadi Liakhovetski 	return send_word(data, 0, idx);
41689551c5SGuennadi Liakhovetski }
42689551c5SGuennadi Liakhovetski 
s6e63d6_param(struct s6e63d6 * data,u16 param)43689551c5SGuennadi Liakhovetski int s6e63d6_param(struct s6e63d6 *data, u16 param)
44689551c5SGuennadi Liakhovetski {
45689551c5SGuennadi Liakhovetski 	return send_word(data, 2, param);
46689551c5SGuennadi Liakhovetski }
47689551c5SGuennadi Liakhovetski 
s6e63d6_init(struct s6e63d6 * data)48689551c5SGuennadi Liakhovetski int s6e63d6_init(struct s6e63d6 *data)
49689551c5SGuennadi Liakhovetski {
50689551c5SGuennadi Liakhovetski 	if (data->id != 0 && data->id != 4) {
51689551c5SGuennadi Liakhovetski 		printf("s6e63d6: invalid ID %u\n", data->id);
52689551c5SGuennadi Liakhovetski 		return 1;
53689551c5SGuennadi Liakhovetski 	}
54689551c5SGuennadi Liakhovetski 
55689551c5SGuennadi Liakhovetski 	data->slave = spi_setup_slave(data->bus, data->cs, 100000, SPI_MODE_3);
56689551c5SGuennadi Liakhovetski 	if (!data->slave)
57689551c5SGuennadi Liakhovetski 		return 1;
58689551c5SGuennadi Liakhovetski 
59689551c5SGuennadi Liakhovetski 	return 0;
60689551c5SGuennadi Liakhovetski }
61