1239278Sgonzo/*- 2239278Sgonzo * Copyright (c) 2011 Jakub Wojciech Klama <jceel@FreeBSD.org> 3239278Sgonzo * All rights reserved. 4239278Sgonzo * 5239278Sgonzo * Redistribution and use in source and binary forms, with or without 6239278Sgonzo * modification, are permitted provided that the following conditions 7239278Sgonzo * are met: 8239278Sgonzo * 1. Redistributions of source code must retain the above copyright 9239278Sgonzo * notice, this list of conditions and the following disclaimer. 10239278Sgonzo * 2. Redistributions in binary form must reproduce the above copyright 11239278Sgonzo * notice, this list of conditions and the following disclaimer in the 12239278Sgonzo * documentation and/or other materials provided with the distribution. 13239278Sgonzo * 14239278Sgonzo * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15239278Sgonzo * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16239278Sgonzo * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17239278Sgonzo * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18239278Sgonzo * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19239278Sgonzo * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20239278Sgonzo * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21239278Sgonzo * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22239278Sgonzo * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23239278Sgonzo * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24239278Sgonzo * SUCH DAMAGE. 25239278Sgonzo * 26239278Sgonzo */ 27239278Sgonzo 28239278Sgonzo#include <sys/cdefs.h> 29239278Sgonzo__FBSDID("$FreeBSD: releng/10.3/sys/arm/lpc/ssd1289.c 239278 2012-08-15 05:37:10Z gonzo $"); 30239278Sgonzo 31239278Sgonzo#include <sys/param.h> 32239278Sgonzo#include <sys/systm.h> 33239278Sgonzo#include <sys/bio.h> 34239278Sgonzo#include <sys/bus.h> 35239278Sgonzo#include <sys/conf.h> 36239278Sgonzo#include <sys/endian.h> 37239278Sgonzo#include <sys/kernel.h> 38239278Sgonzo#include <sys/kthread.h> 39239278Sgonzo#include <sys/lock.h> 40239278Sgonzo#include <sys/malloc.h> 41239278Sgonzo#include <sys/module.h> 42239278Sgonzo#include <sys/mutex.h> 43239278Sgonzo#include <sys/queue.h> 44239278Sgonzo#include <sys/resource.h> 45239278Sgonzo#include <sys/rman.h> 46239278Sgonzo#include <sys/time.h> 47239278Sgonzo#include <sys/timetc.h> 48239278Sgonzo#include <sys/watchdog.h> 49239278Sgonzo 50239278Sgonzo#include <dev/spibus/spi.h> 51239278Sgonzo 52239278Sgonzo#include <dev/ofw/ofw_bus.h> 53239278Sgonzo#include <dev/ofw/ofw_bus_subr.h> 54239278Sgonzo 55239278Sgonzo#include <arm/lpc/lpcreg.h> 56239278Sgonzo#include <arm/lpc/lpcvar.h> 57239278Sgonzo 58239278Sgonzo#include "spibus_if.h" 59239278Sgonzo 60239278Sgonzostruct ssd1289_softc 61239278Sgonzo{ 62239278Sgonzo device_t ss_dev; 63239278Sgonzo}; 64239278Sgonzo 65239278Sgonzostatic int ssd1289_probe(device_t); 66239278Sgonzostatic int ssd1289_attach(device_t); 67239278Sgonzo 68239278Sgonzostatic __inline void ssd1289_set_dc(struct ssd1289_softc *, int); 69239278Sgonzostatic __inline void ssd1289_spi_send(struct ssd1289_softc *, uint8_t *, int); 70239278Sgonzostatic void ssd1289_write_reg(struct ssd1289_softc *, uint16_t, uint16_t); 71239278Sgonzo 72239278Sgonzostatic struct ssd1289_softc *ssd1289_sc = NULL; 73239278Sgonzo 74239278Sgonzovoid ssd1289_configure(void); 75239278Sgonzo 76239278Sgonzostatic int 77239278Sgonzossd1289_probe(device_t dev) 78239278Sgonzo{ 79239278Sgonzo#if 0 80239278Sgonzo if (!ofw_bus_is_compatible(dev, "ssd1289")) 81239278Sgonzo return (ENXIO); 82239278Sgonzo#endif 83239278Sgonzo 84239278Sgonzo device_set_desc(dev, "Solomon Systech SSD1289 LCD controller"); 85239278Sgonzo return (BUS_PROBE_DEFAULT); 86239278Sgonzo} 87239278Sgonzo 88239278Sgonzostatic int 89239278Sgonzossd1289_attach(device_t dev) 90239278Sgonzo{ 91239278Sgonzo struct ssd1289_softc *sc = device_get_softc(dev); 92239278Sgonzo 93239278Sgonzo sc->ss_dev = dev; 94239278Sgonzo ssd1289_sc = sc; 95239278Sgonzo 96239278Sgonzo return (0); 97239278Sgonzo} 98239278Sgonzo 99239278Sgonzovoid 100239278Sgonzossd1289_configure(void) 101239278Sgonzo{ 102239278Sgonzo struct ssd1289_softc *sc = ssd1289_sc; 103239278Sgonzo 104239278Sgonzo /* XXX will be replaced with commented code */ 105239278Sgonzo ssd1289_write_reg(sc,0x00,0x0001); 106239278Sgonzo DELAY(20); 107239278Sgonzo 108239278Sgonzo ssd1289_write_reg(sc,0x03,0xA2A4); 109239278Sgonzo ssd1289_write_reg(sc,0x0C,0x0004); 110239278Sgonzo ssd1289_write_reg(sc,0x0D,0x0308); 111239278Sgonzo ssd1289_write_reg(sc,0x0E,0x3000); 112239278Sgonzo DELAY(50); 113239278Sgonzo 114239278Sgonzo ssd1289_write_reg(sc,0x1E,0x00AF); 115239278Sgonzo ssd1289_write_reg(sc,0x01,0x2B3F); 116239278Sgonzo ssd1289_write_reg(sc,0x02,0x0600); 117239278Sgonzo ssd1289_write_reg(sc,0x10,0x0000); 118239278Sgonzo ssd1289_write_reg(sc,0x07,0x0233); 119239278Sgonzo ssd1289_write_reg(sc,0x0B,0x0039); 120239278Sgonzo ssd1289_write_reg(sc,0x0F,0x0000); 121239278Sgonzo DELAY(50); 122239278Sgonzo 123239278Sgonzo ssd1289_write_reg(sc,0x30,0x0707); 124239278Sgonzo ssd1289_write_reg(sc,0x31,0x0204); 125239278Sgonzo ssd1289_write_reg(sc,0x32,0x0204); 126239278Sgonzo ssd1289_write_reg(sc,0x33,0x0502); 127239278Sgonzo ssd1289_write_reg(sc,0x34,0x0507); 128239278Sgonzo ssd1289_write_reg(sc,0x35,0x0204); 129239278Sgonzo ssd1289_write_reg(sc,0x36,0x0204); 130239278Sgonzo ssd1289_write_reg(sc,0x37,0x0502); 131239278Sgonzo ssd1289_write_reg(sc,0x3A,0x0302); 132239278Sgonzo ssd1289_write_reg(sc,0x3B,0x0302); 133239278Sgonzo 134239278Sgonzo ssd1289_write_reg(sc,0x23,0x0000); 135239278Sgonzo ssd1289_write_reg(sc,0x24,0x0000); 136239278Sgonzo 137239278Sgonzo ssd1289_write_reg(sc,0x48,0x0000); 138239278Sgonzo ssd1289_write_reg(sc,0x49,0x013F); 139239278Sgonzo ssd1289_write_reg(sc,0x4A,0x0000); 140239278Sgonzo ssd1289_write_reg(sc,0x4B,0x0000); 141239278Sgonzo 142239278Sgonzo ssd1289_write_reg(sc,0x41,0x0000); 143239278Sgonzo ssd1289_write_reg(sc,0x42,0x0000); 144239278Sgonzo 145239278Sgonzo ssd1289_write_reg(sc,0x44,0xEF00); 146239278Sgonzo ssd1289_write_reg(sc,0x45,0x0000); 147239278Sgonzo ssd1289_write_reg(sc,0x46,0x013F); 148239278Sgonzo DELAY(50); 149239278Sgonzo 150239278Sgonzo ssd1289_write_reg(sc,0x44,0xEF00); 151239278Sgonzo ssd1289_write_reg(sc,0x45,0x0000); 152239278Sgonzo ssd1289_write_reg(sc,0x4E,0x0000); 153239278Sgonzo ssd1289_write_reg(sc,0x4F,0x0000); 154239278Sgonzo ssd1289_write_reg(sc,0x46,0x013F); 155239278Sgonzo} 156239278Sgonzo 157239278Sgonzostatic __inline void 158239278Sgonzossd1289_spi_send(struct ssd1289_softc *sc, uint8_t *data, int len) 159239278Sgonzo{ 160239278Sgonzo struct spi_command cmd; 161239278Sgonzo uint8_t buffer[8]; 162239278Sgonzo cmd.tx_cmd = data; 163239278Sgonzo cmd.tx_cmd_sz = len; 164239278Sgonzo cmd.rx_cmd = buffer; 165239278Sgonzo cmd.rx_cmd_sz = len; 166239278Sgonzo cmd.tx_data_sz = 0; 167239278Sgonzo cmd.rx_data_sz = 0; 168239278Sgonzo SPIBUS_TRANSFER(device_get_parent(sc->ss_dev), sc->ss_dev, &cmd); 169239278Sgonzo} 170239278Sgonzo 171239278Sgonzostatic __inline void 172239278Sgonzossd1289_set_dc(struct ssd1289_softc *sc, int value) 173239278Sgonzo{ 174239278Sgonzo lpc_gpio_set_state(sc->ss_dev, SSD1289_DC_PIN, value); 175239278Sgonzo} 176239278Sgonzo 177239278Sgonzostatic void 178239278Sgonzossd1289_write_reg(struct ssd1289_softc *sc, uint16_t addr, uint16_t value) 179239278Sgonzo{ 180239278Sgonzo uint8_t buffer[2]; 181239278Sgonzo 182239278Sgonzo ssd1289_set_dc(sc, 0); 183239278Sgonzo buffer[0] = 0x00; 184239278Sgonzo buffer[1] = addr & 0xff; 185239278Sgonzo ssd1289_spi_send(sc, buffer, 2); 186239278Sgonzo 187239278Sgonzo ssd1289_set_dc(sc, 1); 188239278Sgonzo buffer[0] = (value >> 8) & 0xff; 189239278Sgonzo buffer[1] = value & 0xff; 190239278Sgonzo ssd1289_spi_send(sc, buffer, 2); 191239278Sgonzo} 192239278Sgonzo 193239278Sgonzostatic device_method_t ssd1289_methods[] = { 194239278Sgonzo /* Device interface */ 195239278Sgonzo DEVMETHOD(device_probe, ssd1289_probe), 196239278Sgonzo DEVMETHOD(device_attach, ssd1289_attach), 197239278Sgonzo 198239278Sgonzo { 0, 0 } 199239278Sgonzo}; 200239278Sgonzo 201239278Sgonzostatic devclass_t ssd1289_devclass; 202239278Sgonzo 203239278Sgonzostatic driver_t ssd1289_driver = { 204239278Sgonzo "ssd1289", 205239278Sgonzo ssd1289_methods, 206239278Sgonzo sizeof(struct ssd1289_softc), 207239278Sgonzo}; 208239278Sgonzo 209239278SgonzoDRIVER_MODULE(ssd1289, spibus, ssd1289_driver, ssd1289_devclass, 0, 0); 210