summaryrefslogtreecommitdiff
path: root/firmware
diff options
context:
space:
mode:
authorMichael Sevakis <jethead71@rockbox.org>2010-05-18 23:50:00 +0000
committerMichael Sevakis <jethead71@rockbox.org>2010-05-18 23:50:00 +0000
commit54c649697b3959d8f74888bd7ec9af0206f7670c (patch)
treef32061c0514b78d331eb7d9d4b623ae7cffea1f0 /firmware
parent4c6164feced84c7d4a55ec8a5ee3ff398ffc7c53 (diff)
downloadrockbox-54c649697b3959d8f74888bd7ec9af0206f7670c.tar.gz
rockbox-54c649697b3959d8f74888bd7ec9af0206f7670c.zip
Gigabeat S: Implement LCD contrast, invert and flip modes. Enhance LCD power management. Include init data but it's not needed yet (identical to Gigabeat F).
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26154 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r--firmware/export/config/gigabeats.h17
-rw-r--r--firmware/export/imx31l.h154
-rw-r--r--firmware/target/arm/imx31/gigabeat-s/lcd-gigabeat-s.c183
-rw-r--r--firmware/target/arm/imx31/spi-imx31.c6
-rw-r--r--firmware/target/arm/imx31/spi-imx31.h3
5 files changed, 308 insertions, 55 deletions
diff --git a/firmware/export/config/gigabeats.h b/firmware/export/config/gigabeats.h
index b3e7dc31bd..f096fb07d6 100644
--- a/firmware/export/config/gigabeats.h
+++ b/firmware/export/config/gigabeats.h
@@ -120,6 +120,21 @@
120 120
121#ifndef BOOTLOADER 121#ifndef BOOTLOADER
122 122
123/* define this if you can flip your LCD */
124#define HAVE_LCD_FLIP
125
126/* define this if you can invert the colours on your LCD */
127#define HAVE_LCD_INVERT
128
129/* Define this if your LCD can set contrast */
130#define HAVE_LCD_CONTRAST
131
132/* Main LCD contrast range and defaults */
133#define MIN_CONTRAST_SETTING 0
134#define MAX_CONTRAST_SETTING 63
135#define DEFAULT_CONTRAST_SETTING 47 /* Match boot contrast */
136
137/* Define this for LCD backlight brightness available */
123#define HAVE_BACKLIGHT_BRIGHTNESS 138#define HAVE_BACKLIGHT_BRIGHTNESS
124 139
125/* Main LCD backlight brightness range and defaults */ 140/* Main LCD backlight brightness range and defaults */
@@ -139,7 +154,7 @@
139#define CONFIG_I2C I2C_IMX31L 154#define CONFIG_I2C I2C_IMX31L
140 155
141/* Define the bitmask of modules used */ 156/* Define the bitmask of modules used */
142#define SPI_MODULE_MASK (USE_CSPI2_MODULE) 157#define SPI_MODULE_MASK (USE_CSPI2_MODULE | USE_CSPI3_MODULE)
143#define I2C_MODULE_MASK (USE_I2C1_MODULE | USE_I2C2_MODULE) 158#define I2C_MODULE_MASK (USE_I2C1_MODULE | USE_I2C2_MODULE)
144#define GPIO_EVENT_MASK (USE_GPIO1_EVENTS) 159#define GPIO_EVENT_MASK (USE_GPIO1_EVENTS)
145 160
diff --git a/firmware/export/imx31l.h b/firmware/export/imx31l.h
index 3f3a0140c8..7cb452d3cb 100644
--- a/firmware/export/imx31l.h
+++ b/firmware/export/imx31l.h
@@ -197,36 +197,128 @@
197#define RNGA_CONTROL_SLEEP (1 << 4) 197#define RNGA_CONTROL_SLEEP (1 << 4)
198 198
199/* IPU */ 199/* IPU */
200#define IPU_CONF (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x00)) 200#define IPU_IPU_CONF (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x000))
201#define IPU_CHA_BUF0_RDY (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x04)) 201#define IPU_IPU_CHA_BUF0_RDY (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x004))
202#define IPU_CHA_BUF1_RDY (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x08)) 202#define IPU_IPU_CHA_BUF1_RDY (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x008))
203#define IPU_CHA_DB_MODE_SEL (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x0C)) 203#define IPU_IPU_CHA_DB_MODE_SEL (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x00C))
204#define IPU_CHA_CUR_BUF (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x10)) 204#define IPU_IPU_CHA_CUR_BUF (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x010))
205#define IPU_FS_PROC_FLOW (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x14)) 205#define IPU_IPU_FS_PROC_FLOW (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x014))
206#define IPU_FS_DISP_FLOW (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x18)) 206#define IPU_IPU_FS_DISP_FLOW (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x018))
207#define IPU_TASKS_STAT (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x1C)) 207#define IPU_IPU_TASKS_STAT (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x01C))
208#define IPU_IMA_ADDR (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x20)) 208#define IPU_IPU_IMA_ADDR (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x020))
209#define IPU_IMA_DATA (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x24)) 209#define IPU_IPU_IMA_DATA (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x024))
210#define IPU_INT_CTRL_1 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x28)) 210#define IPU_IPU_INT_CTRL_1 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x028))
211#define IPU_INT_CTRL_2 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x2C)) 211#define IPU_IPU_INT_CTRL_2 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x02C))
212#define IPU_INT_CTRL_3 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x30)) 212#define IPU_IPU_INT_CTRL_3 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x030))
213#define IPU_INT_CTRL_4 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x34)) 213#define IPU_IPU_INT_CTRL_4 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x034))
214#define IPU_INT_CTRL_5 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x38)) 214#define IPU_IPU_INT_CTRL_5 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x038))
215#define IPU_INT_STAT_1 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x3C)) 215#define IPU_IPU_INT_STAT_1 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x03C))
216#define IPU_INT_STAT_2 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x40)) 216#define IPU_IPU_INT_STAT_2 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x040))
217#define IPU_INT_STAT_3 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x44)) 217#define IPU_IPU_INT_STAT_3 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x044))
218#define IPU_INT_STAT_4 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x48)) 218#define IPU_IPU_INT_STAT_4 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x048))
219#define IPU_INT_STAT_5 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x4C)) 219#define IPU_IPU_INT_STAT_5 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x04C))
220#define IPU_BRK_CTRL_1 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x50)) 220#define IPU_IPU_BRK_CTRL_1 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x050))
221#define IPU_BRK_CTRL_2 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x54)) 221#define IPU_IPU_BRK_CTRL_2 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x054))
222#define IPU_BRK_STAT (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x58)) 222#define IPU_IPU_BRK_STAT (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x058))
223#define IPU_DIAGB_CTRL (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x60)) 223#define IPU_IPU_DIAGB_CTRL (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x060))
224#define IPU_IDMAC_CONF (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0xA4)) 224#define IPU_CSI_SENS_FRM_SIZE (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x064))
225#define IPU_IDMAC_CHA_EN (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0xA8)) 225#define IPU_CSI_ACT_FRM_SIZE (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x068))
226#define IPU_IDMAC_CHA_PRI (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0xAC)) 226#define IPU_CSI_OUT_FRM_CTRL (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x06C))
227#define IPU_IDMAC_CHA_BUSY (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0xB0)) 227#define IPU_CSI_TST_CTRL (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x070))
228 228#define IPU_CSI_CCIR_CODE_1 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x074))
229 229#define IPU_CSI_CCIR_CODE_2 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x078))
230#define IPU_CSI_CCIR_CODE_3 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x07C))
231#define IPU_CSI_FLASH_STROBE_1 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x080))
232#define IPU_CSI_FLASH_STROBE_2 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x084))
233#define IPU_IC_CONF (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x088))
234#define IPU_IC_PRP_ENC_RSC (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x08C))
235#define IPU_IC_PRP_VF_RSC (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x090))
236#define IPU_IC_PP_RSC (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x094))
237#define IPU_IC_CMBP_1 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x098))
238#define IPU_IC_CMBP_2 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x09C))
239#define IPU_PF_CONF (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x0A0))
240#define IPU_IDMAC_CONF (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x0A4))
241#define IPU_IDMAC_CHA_EN (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x0A8))
242#define IPU_IDMAC_CHA_PRI (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x0AC))
243#define IPU_IDMAC_CHA_BUSY (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x0B0))
244#define IPU_SDC_COM_CONF (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x0B4))
245#define IPU_SDC_GRAPH_WIND_CTRL (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x0B8))
246#define IPU_SDC_FG_POS (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x0BC))
247#define IPU_SDC_BG_POS (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x0C0))
248#define IPU_SDC_CUR_POS (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x0C4))
249#define IPU_SDC_CUR_BLINK_PWM_CTRL (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x0C8))
250#define IPU_SDC_CUR_MAP (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x0CC))
251#define IPU_SDC_HOR_CONF (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x0D0))
252#define IPU_SDC_VER_CONF (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x0D4))
253#define IPU_SDC_SHARP_CONF_1 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x0D8))
254#define IPU_SDC_SHARP_CONF_2 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x0DC))
255#define IPU_SDC_ADC_CONF (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x0E0))
256#define IPU_ADC_SYSCHA1_SA (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x0E4))
257#define IPU_ADC_SYSCHA2_SA (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x0E8))
258#define IPU_ADC_PRPCHAN_SA (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x0EC))
259#define IPU_ADC_PPCHAN_SA (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x0F0))
260#define IPU_ADC_DISP0_CONF (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x0F4))
261#define IPU_ADC_DISP0_RD_AP (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x0F8))
262#define IPU_ADC_DISP0_RDM (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x0FC))
263#define IPU_ADC_DISP0_SS (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x100))
264#define IPU_ADC_DISP1_CONF (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x104))
265#define IPU_ADC_DISP1_RD_AP (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x108))
266#define IPU_ADC_DISP1_RDM (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x10C))
267#define IPU_ADC_DISP2_SS (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x110))
268#define IPU_ADC_DISP2_CONF (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x114))
269#define IPU_ADC_DISP2_RD_AP (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x118))
270#define IPU_ADC_DISP2_RDM (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x11C))
271#define IPU_ADC_DISP_VSYNC (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x120))
272#define IPU_ADC_DISP_IF_CONF (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x124))
273#define IPU_ADC_DISP_SIG_POL (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x128))
274#define IPU_DI_SER_DISP1_CONF (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x12C))
275#define IPU_DI_SER_DISP2_CONF (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x130))
276#define IPU_DI_HSP_CLK_PER (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x134))
277#define IPU_DI_DISP0_TIME_CONF_1 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x138))
278#define IPU_DI_DISP0_TIME_CONF_2 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x13C))
279#define IPU_DI_DISP0_TIME_CONF_3 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x140))
280#define IPU_DI_DISP1_TIME_CONF_1 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x144))
281#define IPU_DI_DISP1_TIME_CONF_2 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x148))
282#define IPU_DI_DISP1_TIME_CONF_3 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x14C))
283#define IPU_DI_DISP2_TIME_CONF_1 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x150))
284#define IPU_DI_DISP2_TIME_CONF_2 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x154))
285#define IPU_DI_DISP2_TIME_CONF_3 (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x158))
286#define IPU_DI_DISP3_TIME_CONF (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x15C))
287#define IPU_DI_DISP0_DB0_MAP (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x160))
288#define IPU_DI_DISP0_DB1_MAP (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x164))
289#define IPU_DI_DISP0_DB2_MAP (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x168))
290#define IPU_DI_DISP0_CB0_MAP (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x16C))
291#define IPU_DI_DISP0_CB1_MAP (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x170))
292#define IPU_DI_DISP0_CB2_MAP (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x174))
293#define IPU_DI_DISP1_DB0_MAP (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x178))
294#define IPU_DI_DISP1_DB1_MAP (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x17C))
295#define IPU_DI_DISP1_DB2_MAP (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x180))
296#define IPU_DI_DISP1_CB0_MAP (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x184))
297#define IPU_DI_DISP1_CB1_MAP (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x188))
298#define IPU_DI_DISP1_CB2_MAP (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x18C))
299#define IPU_DI_DISP2_DB0_MAP (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x190))
300#define IPU_DI_DISP2_DB1_MAP (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x194))
301#define IPU_DI_DISP2_DB2_MAP (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x198))
302#define IPU_DI_DISP2_CB0_MAP (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x19C))
303#define IPU_DI_DISP2_CB1_MAP (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x1A0))
304#define IPU_DI_DISP2_CB2_MAP (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x1A4))
305#define IPU_DI_DISP3_B0_MAP (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x1A8))
306#define IPU_DI_DISP3_B1_MAP (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x1AC))
307#define IPU_DI_DISP3_B2_MAP (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x1B0))
308#define IPU_DI_DISP_ACC_CC (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x1B4))
309#define IPU_DI_DISP_LLA_CONF (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x1B8))
310#define IPU_DI_DISP_LLA_DATA (*(REG32_PTR_T)(IPU_CTRL_BASE_ADDR+0x1BC))
311
312/* IPU_CONF */
313#define IPU_IPU_CONF_PXL_ENDIAN (1 << 8)
314#define IPU_IPU_CONF_DU_EN (1 << 7)
315#define IPU_IPU_CONF_DI_EN (1 << 6)
316#define IPU_IPU_CONF_ADC_EN (1 << 5)
317#define IPU_IPU_CONF_SDC_EN (1 << 4)
318#define IPU_IPU_CONF_PF_EN (1 << 3)
319#define IPU_IPU_CONF_ROT_EN (1 << 2)
320#define IPU_IPU_CONF_IC_EN (1 << 1)
321#define IPU_IPU_CONF_CSI_EN (1 << 0)
230 322
231/* ATA */ 323/* ATA */
232#define ATA_TIME_OFF (*(REG8_PTR_T)(ATA_BASE_ADDR+0x00)) 324#define ATA_TIME_OFF (*(REG8_PTR_T)(ATA_BASE_ADDR+0x00))
@@ -493,7 +585,7 @@
493#define CSPI_BITCOUNT(n) ((n) << 8) 585#define CSPI_BITCOUNT(n) ((n) << 8)
494#define CSPI_CONREG_SSPOL (1 << 7) 586#define CSPI_CONREG_SSPOL (1 << 7)
495#define CSPI_CONREG_SSCTL (1 << 6) 587#define CSPI_CONREG_SSCTL (1 << 6)
496#define CSPI_CONREG_PHA (1 << 6) 588#define CSPI_CONREG_PHA (1 << 5)
497#define CSPI_CONREG_POL (1 << 4) 589#define CSPI_CONREG_POL (1 << 4)
498#define CSPI_CONREG_SMC (1 << 3) 590#define CSPI_CONREG_SMC (1 << 3)
499#define CSPI_CONREG_XCH (1 << 2) 591#define CSPI_CONREG_XCH (1 << 2)
diff --git a/firmware/target/arm/imx31/gigabeat-s/lcd-gigabeat-s.c b/firmware/target/arm/imx31/gigabeat-s/lcd-gigabeat-s.c
index fd0aebe3a2..fbcd54059e 100644
--- a/firmware/target/arm/imx31/gigabeat-s/lcd-gigabeat-s.c
+++ b/firmware/target/arm/imx31/gigabeat-s/lcd-gigabeat-s.c
@@ -22,7 +22,10 @@
22#include "inttypes.h" 22#include "inttypes.h"
23 23
24#include "config.h" 24#include "config.h"
25#include "system.h"
25#include "cpu.h" 26#include "cpu.h"
27#include "spi-imx31.h"
28#include "mc13783.h"
26#include "string.h" 29#include "string.h"
27#include "lcd.h" 30#include "lcd.h"
28#include "kernel.h" 31#include "kernel.h"
@@ -32,16 +35,117 @@
32#define MAIN_LCD_IDMAC_CHANNEL 14 35#define MAIN_LCD_IDMAC_CHANNEL 14
33#define LCDADDR(x, y) (&lcd_framebuffer[(y)][(x)]) 36#define LCDADDR(x, y) (&lcd_framebuffer[(y)][(x)])
34 37
35static bool lcd_on = true;
36static bool lcd_powered = true;
37static unsigned lcd_yuv_options = 0;
38
39/* Copies a rectangle from one framebuffer to another. Can be used in 38/* Copies a rectangle from one framebuffer to another. Can be used in
40 single transfer mode with width = num pixels, and height = 1 which 39 single transfer mode with width = num pixels, and height = 1 which
41 allows a full-width rectangle to be copied more efficiently. */ 40 allows a full-width rectangle to be copied more efficiently. */
42extern void lcd_copy_buffer_rect(fb_data *dst, const fb_data *src, 41extern void lcd_copy_buffer_rect(fb_data *dst, const fb_data *src,
43 int width, int height); 42 int width, int height);
44 43
44static bool lcd_on = true;
45static bool lcd_powered = true;
46static unsigned lcd_yuv_options = 0;
47
48#if 0
49/* Initialization data from OF bootloader. Identical to Gigabeat F/X. */
50static const unsigned char lcd_init_data[50] =
51{
52 /* Reg Val */
53 0x0f, 0x01,
54 0x09, 0x06,
55 0x16, 0xa6,
56 0x1e, 0x49,
57 0x1f, 0x26,
58 0x0b, 0x2f, /* Set contrast 0-63 */
59 0x0c, 0x2b,
60 0x19, 0x5e,
61 0x1a, 0x15,
62 0x1b, 0x15,
63 0x1d, 0x01,
64 0x00, 0x03,
65 0x01, 0x10,
66 0x02, 0x0a,
67 0x06, 0x04, /* Set the orientation 2=upside down, 4=normal */
68 0x08, 0x2e,
69 0x24, 0x12,
70 0x25, 0x3f,
71 0x26, 0x0b,
72 0x27, 0x00,
73 0x28, 0x00,
74 0x29, 0xf6,
75 0x2a, 0x03,
76 0x2b, 0x0a,
77 0x04, 0x01, /* Display ON */
78};
79#endif
80
81static const struct spi_node lcd_spi_node =
82{
83 /* Original firmware settings for LCD panel commication */
84 CSPI3_NUM, /* CSPI module 3 */
85 CSPI_CONREG_CHIP_SELECT_SS1 | /* Chip select 1 */
86 CSPI_CONREG_DRCTL_DONT_CARE | /* Don't care about CSPI_RDY */
87 CSPI_CONREG_DATA_RATE_DIV_16 | /* Clock = IPG_CLK/16 = 4,125,000Hz. */
88 CSPI_BITCOUNT(32-1) | /* All 32 bits are to be transferred */
89 CSPI_CONREG_SSPOL | /* SS active high */
90 CSPI_CONREG_PHA | /* Phase 1 operation */
91 CSPI_CONREG_POL | /* Active low polarity */
92 CSPI_CONREG_MODE, /* Master mode */
93 0, /* SPI clock - no wait states */
94};
95
96static void lcd_write_reg(unsigned reg, unsigned val)
97{
98 /* packet: |00|rr|01|vv| */
99 uint32_t packet = ((reg & 0xff) << 16) | 0x0100 | (val & 0xff);
100
101 struct spi_transfer_desc xfer;
102
103 xfer.node = &lcd_spi_node;
104 xfer.txbuf = &packet;
105 xfer.rxbuf = NULL;
106 xfer.count = 1;
107 xfer.callback = NULL;
108 xfer.next = NULL;
109
110 if (spi_transfer(&xfer))
111 {
112 /* Just busy wait; the interface is not used very much */
113 while (!spi_transfer_complete(&xfer));
114 }
115}
116
117static void lcd_enable_interface(bool enable)
118{
119 if (enable)
120 {
121 spi_enable_module(&lcd_spi_node);
122 }
123 else
124 {
125 spi_disable_module(&lcd_spi_node);
126 }
127}
128
129static void lcd_set_power(bool powered)
130{
131 if (powered)
132 {
133 lcd_powered = false;
134 lcd_write_reg(0x04, 0x00);
135 lcd_enable_interface(false);
136 imx31_regclr32(&GPIO3_DR, (1 << 12));
137 mc13783_clear(MC13783_REGULATOR_MODE1, MC13783_VCAMEN);
138 }
139 else
140 {
141 mc13783_set(MC13783_REGULATOR_MODE1, MC13783_VCAMEN);
142 imx31_regset32(&GPIO3_DR, (1 << 12));
143 lcd_enable_interface(true);
144 lcd_write_reg(0x04, 0x01);
145 lcd_powered = true;
146 }
147}
148
45/* LCD init */ 149/* LCD init */
46void lcd_init_device(void) 150void lcd_init_device(void)
47{ 151{
@@ -50,8 +154,19 @@ void lcd_init_device(void)
50 /* Only do this once to avoid flicker */ 154 /* Only do this once to avoid flicker */
51 memset(FRAME, 0x00, FRAME_SIZE); 155 memset(FRAME, 0x00, FRAME_SIZE);
52#endif 156#endif
53 IPU_IMA_ADDR = ((0x1 << 16) | (MAIN_LCD_IDMAC_CHANNEL << 4)) + (1 << 3); 157 IPU_IPU_IMA_ADDR = ((0x1 << 16) | (MAIN_LCD_IDMAC_CHANNEL << 4)) + (1 << 3);
54 IPU_IMA_DATA = FRAME_PHYS_ADDR; 158 IPU_IPU_IMA_DATA = FRAME_PHYS_ADDR;
159
160 lcd_enable_interface(true);
161#ifdef HAVE_LCD_CONTRAST
162 lcd_set_contrast(DEFAULT_CONTRAST_SETTING);
163#endif
164#ifdef HAVE_LCD_INVERT
165 lcd_set_invert_display(false);
166#endif
167#ifdef HAVE_LCD_FLIP
168 lcd_set_flip(false);
169#endif
55} 170}
56 171
57/* Update a fraction of the display. */ 172/* Update a fraction of the display. */
@@ -96,13 +211,14 @@ void lcd_update_rect(int x, int y, int width, int height)
96 211
97void lcd_sleep(void) 212void lcd_sleep(void)
98{ 213{
99 if (lcd_powered) 214 if (!lcd_powered)
100 { 215 return;
101 lcd_enable(false); 216
102 lcd_powered = false; 217 IPU_IDMAC_CHA_EN &= ~(1ul << MAIN_LCD_IDMAC_CHANNEL);
103 IPU_IDMAC_CHA_EN &= ~(1ul << MAIN_LCD_IDMAC_CHANNEL); 218 IPU_IPU_CONF &= ~IPU_IPU_CONF_ADC_EN;
104 _backlight_lcd_sleep(); 219 lcd_enable(false);
105 } 220 lcd_set_power(false);
221 _backlight_lcd_sleep();
106} 222}
107 223
108void lcd_enable(bool state) 224void lcd_enable(bool state)
@@ -112,9 +228,11 @@ void lcd_enable(bool state)
112 228
113 if (state) 229 if (state)
114 { 230 {
231 if (!lcd_powered)
232 lcd_set_power(true);
233 IPU_IPU_CONF |= IPU_IPU_CONF_ADC_EN;
115 IPU_IDMAC_CHA_EN |= 1ul << MAIN_LCD_IDMAC_CHANNEL; 234 IPU_IDMAC_CHA_EN |= 1ul << MAIN_LCD_IDMAC_CHANNEL;
116 sleep(HZ/50); 235 sleep(HZ/50);
117 lcd_powered = true;
118 lcd_on = true; 236 lcd_on = true;
119 lcd_update(); 237 lcd_update();
120 send_event(LCD_EVENT_ACTIVATION, NULL); 238 send_event(LCD_EVENT_ACTIVATION, NULL);
@@ -211,18 +329,37 @@ void lcd_blit_yuv(unsigned char * const src[3],
211 } 329 }
212} 330}
213 331
214void lcd_set_contrast(int val) { 332#ifdef HAVE_LCD_CONTRAST
215 (void) val; 333void lcd_set_contrast(int val)
216 // TODO: 334{
335 if (!lcd_on)
336 return;
337
338 lcd_write_reg(0x0b, val);
217} 339}
218 340
219void lcd_set_invert_display(bool yesno) { 341int lcd_default_contrast(void)
220 (void) yesno; 342{
221 // TODO: 343 return DEFAULT_CONTRAST_SETTING;
222} 344}
345#endif /* HAVE_LCD_CONTRAST */
223 346
224void lcd_set_flip(bool yesno) { 347#ifdef HAVE_LCD_INVERT
225 (void) yesno; 348void lcd_set_invert_display(bool yesno)
226 // TODO: 349{
350 if (!lcd_on)
351 return;
352
353 lcd_write_reg(0x27, yesno ? 0x10 : 00);
227} 354}
355#endif /* HAVE_LCD_INVERT */
228 356
357#ifdef HAVE_LCD_FLIP
358void lcd_set_flip(bool yesno)
359{
360 if (!lcd_on)
361 return;
362
363 lcd_write_reg(0x06, yesno ? 0x02 : 0x04);
364}
365#endif /* HAVE_LCD_FLIP */
diff --git a/firmware/target/arm/imx31/spi-imx31.c b/firmware/target/arm/imx31/spi-imx31.c
index e6dddd65c1..e0187e4388 100644
--- a/firmware/target/arm/imx31/spi-imx31.c
+++ b/firmware/target/arm/imx31/spi-imx31.c
@@ -435,3 +435,9 @@ bool spi_transfer(struct spi_transfer_desc *xfer)
435 435
436 return retval; 436 return retval;
437} 437}
438
439/* Returns 'true' if the descriptor is not busy */
440bool spi_transfer_complete(const struct spi_transfer_desc *xfer)
441{
442 return xfer->next == NULL;
443}
diff --git a/firmware/target/arm/imx31/spi-imx31.h b/firmware/target/arm/imx31/spi-imx31.h
index 71f9512103..35b7d514cf 100644
--- a/firmware/target/arm/imx31/spi-imx31.h
+++ b/firmware/target/arm/imx31/spi-imx31.h
@@ -83,4 +83,7 @@ void spi_disable_module(const struct spi_node *node);
83/* Send and/or receive data on the specified node (asychronous) */ 83/* Send and/or receive data on the specified node (asychronous) */
84bool spi_transfer(struct spi_transfer_desc *xfer); 84bool spi_transfer(struct spi_transfer_desc *xfer);
85 85
86/* Returns 'true' if the descriptor is not busy */
87bool spi_transfer_complete(const struct spi_transfer_desc *xfer);
88
86#endif /* SPI_IMX31_H */ 89#endif /* SPI_IMX31_H */