2 * linux/drivers/video/mmp/hw/mmp_spi.c
3 * using the spi in LCD controler for commands send
5 * Copyright (C) 2012 Marvell Technology Group Ltd.
6 * Authors: Guoqing Li <ligq@marvell.com>
7 * Lisa Du <cldu@marvell.com>
8 * Zhou Zhu <zzhu3@marvell.com>
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
15 * This program is distributed in the hope that it will be useful, but WITHOUT
16 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
17 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
20 * You should have received a copy of the GNU General Public License along with
21 * this program. If not, see <http://www.gnu.org/licenses/>.
24 #include <linux/errno.h>
25 #include <linux/delay.h>
26 #include <linux/err.h>
28 #include <linux/spi/spi.h>
32 * spi_write - write command to the SPI port
33 * @data: can be 8/16/32-bit, MSB justified data to write.
36 * Wait bus transfer complete IRQ.
37 * The caller is expected to perform the necessary locking.
40 * %-ETIMEDOUT timeout occurred
43 static inline int lcd_spi_write(struct spi_device
*spi
, u32 data
)
45 int timeout
= 100000, isr
, ret
= 0;
48 *(void **)spi_master_get_devdata(spi
->master
);
51 writel_relaxed(~SPI_IRQ_MASK
, reg_base
+ SPU_IRQ_ISR
);
53 switch (spi
->bits_per_word
) {
55 writel_relaxed((u8
)data
, reg_base
+ LCD_SPU_SPI_TXDATA
);
58 writel_relaxed((u16
)data
, reg_base
+ LCD_SPU_SPI_TXDATA
);
61 writel_relaxed((u32
)data
, reg_base
+ LCD_SPU_SPI_TXDATA
);
64 dev_err(&spi
->dev
, "Wrong spi bit length\n");
67 /* SPI start to send command */
68 tmp
= readl_relaxed(reg_base
+ LCD_SPU_SPI_CTRL
);
69 tmp
&= ~CFG_SPI_START_MASK
;
70 tmp
|= CFG_SPI_START(1);
71 writel(tmp
, reg_base
+ LCD_SPU_SPI_CTRL
);
73 isr
= readl_relaxed(reg_base
+ SPU_IRQ_ISR
);
74 while (!(isr
& SPI_IRQ_ENA_MASK
)) {
76 isr
= readl_relaxed(reg_base
+ SPU_IRQ_ISR
);
79 dev_err(&spi
->dev
, "spi cmd send time out\n");
84 tmp
= readl_relaxed(reg_base
+ LCD_SPU_SPI_CTRL
);
85 tmp
&= ~CFG_SPI_START_MASK
;
86 tmp
|= CFG_SPI_START(0);
87 writel_relaxed(tmp
, reg_base
+ LCD_SPU_SPI_CTRL
);
89 writel_relaxed(~SPI_IRQ_MASK
, reg_base
+ SPU_IRQ_ISR
);
94 static int lcd_spi_setup(struct spi_device
*spi
)
97 *(void **)spi_master_get_devdata(spi
->master
);
100 tmp
= CFG_SCLKCNT(16) |
101 CFG_TXBITS(spi
->bits_per_word
) |
102 CFG_SPI_SEL(1) | CFG_SPI_ENA(1) |
104 writel(tmp
, reg_base
+ LCD_SPU_SPI_CTRL
);
107 * After set mode it need a time to pull up the spi singals,
108 * or it would cause the wrong waveform when send spi command,
109 * especially on pxa910h
111 tmp
= readl_relaxed(reg_base
+ SPU_IOPAD_CONTROL
);
112 if ((tmp
& CFG_IOPADMODE_MASK
) != IOPAD_DUMB18SPI
)
113 writel_relaxed(IOPAD_DUMB18SPI
|
114 (tmp
& ~CFG_IOPADMODE_MASK
),
115 reg_base
+ SPU_IOPAD_CONTROL
);
120 static int lcd_spi_one_transfer(struct spi_device
*spi
, struct spi_message
*m
)
122 struct spi_transfer
*t
;
125 list_for_each_entry(t
, &m
->transfers
, transfer_list
) {
126 switch (spi
->bits_per_word
) {
128 for (i
= 0; i
< t
->len
; i
++)
129 lcd_spi_write(spi
, ((u8
*)t
->tx_buf
)[i
]);
132 for (i
= 0; i
< t
->len
/2; i
++)
133 lcd_spi_write(spi
, ((u16
*)t
->tx_buf
)[i
]);
136 for (i
= 0; i
< t
->len
/4; i
++)
137 lcd_spi_write(spi
, ((u32
*)t
->tx_buf
)[i
]);
140 dev_err(&spi
->dev
, "Wrong spi bit length\n");
146 m
->complete(m
->context
);
150 int lcd_spi_register(struct mmphw_ctrl
*ctrl
)
152 struct spi_master
*master
;
156 master
= spi_alloc_master(ctrl
->dev
, sizeof(void *));
158 dev_err(ctrl
->dev
, "unable to allocate SPI master\n");
161 p_regbase
= spi_master_get_devdata(master
);
162 *p_regbase
= ctrl
->reg_base
;
164 /* set bus num to 5 to avoid conflict with other spi hosts */
166 master
->num_chipselect
= 1;
167 master
->setup
= lcd_spi_setup
;
168 master
->transfer
= lcd_spi_one_transfer
;
170 err
= spi_register_master(master
);
172 dev_err(ctrl
->dev
, "unable to register SPI master\n");
173 spi_master_put(master
);
177 dev_info(&master
->dev
, "registered\n");