1/*- 2 * Copyright (c) 2011 Jakub Wojciech Klama <jceel@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 * 26 */ 27 28#include <sys/cdefs.h> 29__FBSDID("$FreeBSD: releng/10.2/sys/arm/lpc/ssd1289.c 239278 2012-08-15 05:37:10Z gonzo $"); 30 31#include <sys/param.h> 32#include <sys/systm.h> 33#include <sys/bio.h> 34#include <sys/bus.h> 35#include <sys/conf.h> 36#include <sys/endian.h> 37#include <sys/kernel.h> 38#include <sys/kthread.h> 39#include <sys/lock.h> 40#include <sys/malloc.h> 41#include <sys/module.h> 42#include <sys/mutex.h> 43#include <sys/queue.h> 44#include <sys/resource.h> 45#include <sys/rman.h> 46#include <sys/time.h> 47#include <sys/timetc.h> 48#include <sys/watchdog.h> 49 50#include <dev/spibus/spi.h> 51 52#include <dev/ofw/ofw_bus.h> 53#include <dev/ofw/ofw_bus_subr.h> 54 55#include <arm/lpc/lpcreg.h> 56#include <arm/lpc/lpcvar.h> 57 58#include "spibus_if.h" 59 60struct ssd1289_softc 61{ 62 device_t ss_dev; 63}; 64 65static int ssd1289_probe(device_t); 66static int ssd1289_attach(device_t); 67 68static __inline void ssd1289_set_dc(struct ssd1289_softc *, int); 69static __inline void ssd1289_spi_send(struct ssd1289_softc *, uint8_t *, int); 70static void ssd1289_write_reg(struct ssd1289_softc *, uint16_t, uint16_t); 71 72static struct ssd1289_softc *ssd1289_sc = NULL; 73 74void ssd1289_configure(void); 75 76static int 77ssd1289_probe(device_t dev) 78{ 79#if 0 80 if (!ofw_bus_is_compatible(dev, "ssd1289")) 81 return (ENXIO); 82#endif 83 84 device_set_desc(dev, "Solomon Systech SSD1289 LCD controller"); 85 return (BUS_PROBE_DEFAULT); 86} 87 88static int 89ssd1289_attach(device_t dev) 90{ 91 struct ssd1289_softc *sc = device_get_softc(dev); 92 93 sc->ss_dev = dev; 94 ssd1289_sc = sc; 95 96 return (0); 97} 98 99void 100ssd1289_configure(void) 101{ 102 struct ssd1289_softc *sc = ssd1289_sc; 103 104 /* XXX will be replaced with commented code */ 105 ssd1289_write_reg(sc,0x00,0x0001); 106 DELAY(20); 107 108 ssd1289_write_reg(sc,0x03,0xA2A4); 109 ssd1289_write_reg(sc,0x0C,0x0004); 110 ssd1289_write_reg(sc,0x0D,0x0308); 111 ssd1289_write_reg(sc,0x0E,0x3000); 112 DELAY(50); 113 114 ssd1289_write_reg(sc,0x1E,0x00AF); 115 ssd1289_write_reg(sc,0x01,0x2B3F); 116 ssd1289_write_reg(sc,0x02,0x0600); 117 ssd1289_write_reg(sc,0x10,0x0000); 118 ssd1289_write_reg(sc,0x07,0x0233); 119 ssd1289_write_reg(sc,0x0B,0x0039); 120 ssd1289_write_reg(sc,0x0F,0x0000); 121 DELAY(50); 122 123 ssd1289_write_reg(sc,0x30,0x0707); 124 ssd1289_write_reg(sc,0x31,0x0204); 125 ssd1289_write_reg(sc,0x32,0x0204); 126 ssd1289_write_reg(sc,0x33,0x0502); 127 ssd1289_write_reg(sc,0x34,0x0507); 128 ssd1289_write_reg(sc,0x35,0x0204); 129 ssd1289_write_reg(sc,0x36,0x0204); 130 ssd1289_write_reg(sc,0x37,0x0502); 131 ssd1289_write_reg(sc,0x3A,0x0302); 132 ssd1289_write_reg(sc,0x3B,0x0302); 133 134 ssd1289_write_reg(sc,0x23,0x0000); 135 ssd1289_write_reg(sc,0x24,0x0000); 136 137 ssd1289_write_reg(sc,0x48,0x0000); 138 ssd1289_write_reg(sc,0x49,0x013F); 139 ssd1289_write_reg(sc,0x4A,0x0000); 140 ssd1289_write_reg(sc,0x4B,0x0000); 141 142 ssd1289_write_reg(sc,0x41,0x0000); 143 ssd1289_write_reg(sc,0x42,0x0000); 144 145 ssd1289_write_reg(sc,0x44,0xEF00); 146 ssd1289_write_reg(sc,0x45,0x0000); 147 ssd1289_write_reg(sc,0x46,0x013F); 148 DELAY(50); 149 150 ssd1289_write_reg(sc,0x44,0xEF00); 151 ssd1289_write_reg(sc,0x45,0x0000); 152 ssd1289_write_reg(sc,0x4E,0x0000); 153 ssd1289_write_reg(sc,0x4F,0x0000); 154 ssd1289_write_reg(sc,0x46,0x013F); 155} 156 157static __inline void 158ssd1289_spi_send(struct ssd1289_softc *sc, uint8_t *data, int len) 159{ 160 struct spi_command cmd; 161 uint8_t buffer[8]; 162 cmd.tx_cmd = data; 163 cmd.tx_cmd_sz = len; 164 cmd.rx_cmd = buffer; 165 cmd.rx_cmd_sz = len; 166 cmd.tx_data_sz = 0; 167 cmd.rx_data_sz = 0; 168 SPIBUS_TRANSFER(device_get_parent(sc->ss_dev), sc->ss_dev, &cmd); 169} 170 171static __inline void 172ssd1289_set_dc(struct ssd1289_softc *sc, int value) 173{ 174 lpc_gpio_set_state(sc->ss_dev, SSD1289_DC_PIN, value); 175} 176 177static void 178ssd1289_write_reg(struct ssd1289_softc *sc, uint16_t addr, uint16_t value) 179{ 180 uint8_t buffer[2]; 181 182 ssd1289_set_dc(sc, 0); 183 buffer[0] = 0x00; 184 buffer[1] = addr & 0xff; 185 ssd1289_spi_send(sc, buffer, 2); 186 187 ssd1289_set_dc(sc, 1); 188 buffer[0] = (value >> 8) & 0xff; 189 buffer[1] = value & 0xff; 190 ssd1289_spi_send(sc, buffer, 2); 191} 192 193static device_method_t ssd1289_methods[] = { 194 /* Device interface */ 195 DEVMETHOD(device_probe, ssd1289_probe), 196 DEVMETHOD(device_attach, ssd1289_attach), 197 198 { 0, 0 } 199}; 200 201static devclass_t ssd1289_devclass; 202 203static driver_t ssd1289_driver = { 204 "ssd1289", 205 ssd1289_methods, 206 sizeof(struct ssd1289_softc), 207}; 208 209DRIVER_MODULE(ssd1289, spibus, ssd1289_driver, ssd1289_devclass, 0, 0); 210