lcd.c (3793B)
1 /* 2 * 3 * This license is set out in https://raw.githubusercontent.com/Broadcom-Network-Switching-Software/OpenBCM/master/Legal/LICENSE file. 4 * 5 * Copyright 2007-2019 Broadcom Inc. All rights reserved. 6 * 7 * BCM56xx I2C Device Driver for Matrix Orbital LCD Controller/Display 8 * command set. The Matrix Orbital display is an LCD display with an 9 * I2C interface and command set. 10 * 11 * See also: Matrix Orbital (http://www.matrix-orbital.com/) 12 */ 13 #include <sal/types.h> 14 #include <soc/drv.h> 15 #include <soc/error.h> 16 #include <soc/i2c.h> 17 18 /* Matrix Orbital LCD 204x (20x4) */ 19 #define NUM_LCD_COLUMNS 20 20 #define NUM_LCD_ROWS 4 21 #define LCD_COMMAND 0xfe 22 23 24 STATIC int 25 lcd_read(int unit, int devno, 26 uint16 addr, uint8* data, uint32* len) 27 { 28 COMPILER_REFERENCE(unit); 29 COMPILER_REFERENCE(devno); 30 COMPILER_REFERENCE(data); 31 32 *len = 0; 33 return SOC_E_NONE; 34 } 35 36 STATIC int 37 lcd_write(int unit, int devno, 38 uint16 addr, uint8* data, uint32 len) 39 { 40 int rv = SOC_E_NONE; 41 uint8 saddr = soc_i2c_addr(unit, devno); 42 uint32 i; 43 44 for(i = 0; i < len; i++) { 45 rv |= soc_i2c_write_byte(unit, saddr, *data++); 46 soc_i2c_device(unit, devno)->tbyte++; 47 } 48 return rv; 49 } 50 51 STATIC void 52 lcd_config(int unit, int devid, 53 char columns, char rows) 54 { 55 uint8 buffer[4]; 56 57 buffer[0] = LCD_COMMAND; 58 buffer[1] = 'I'; 59 buffer[2] = columns; 60 buffer[3] = rows; 61 lcd_write(unit, devid, 0, buffer, 4); 62 } 63 64 STATIC void 65 lcd_ttymode(int unit, int devid){ 66 uint8 buffer[4]; 67 68 /* Turn on auto-scroll and auto-wrap */ 69 buffer[0] = LCD_COMMAND; 70 buffer[1] = 'C'; /* Auto line-wrap mode */ 71 buffer[2] = LCD_COMMAND; 72 buffer[3] = 'Q'; /* Auto scroll mode */ 73 lcd_write(unit, devid, 0, buffer, 4); 74 } 75 76 STATIC void 77 lcd_cls(int unit, int devid){ 78 uint8 buffer[4]; 79 80 buffer[0] = LCD_COMMAND; 81 /* Goto upper left hand corner (0,0) */ 82 buffer[1] = 0x47; 83 buffer[2] = 0; 84 buffer[3] = 0; 85 lcd_write(unit, devid, 0, buffer, 4); 86 buffer[1] = 'X'; /* Clear screen */ 87 lcd_write(unit, devid, 0, buffer, 2); 88 89 } 90 91 STATIC void 92 lcd_contrast(int unit, int devid, uint8 val) 93 { 94 uint8 buffer[3]; 95 96 /* Turn on auto-scroll and auto-wrap */ 97 buffer[0] = LCD_COMMAND; 98 buffer[1] = 0x50; /* Clear screen */ 99 buffer[2] = val; 100 lcd_write(unit, devid, 0, buffer, 3); 101 } 102 103 STATIC int 104 lcd_ioctl(int unit, int devno, 105 int opcode, void* data, int len) 106 { 107 switch (opcode) { 108 109 case I2C_LCD_CLS: 110 lcd_cls(unit, devno); 111 break; 112 113 case I2C_LCD_CONTRAST: 114 if(!data) 115 break; 116 else { 117 uint8 db = *((uint8*)data); 118 lcd_contrast(unit, devno, db); 119 } 120 break; 121 case I2C_LCD_CONFIG: 122 lcd_config(unit, devno, NUM_LCD_COLUMNS, NUM_LCD_ROWS); 123 break; 124 125 default: 126 break; 127 } 128 return SOC_E_NONE; 129 } 130 131 132 133 STATIC int 134 lcd_init(int unit, int devno, 135 void* data, int len) 136 { 137 int i; 138 char *buf; 139 140 soc_i2c_devdesc_set(unit, devno, 141 "Matrix Orbital LCD (http://www.matrix-orbital.com)"); 142 143 buf = sal_alloc(128,"lcd"); 144 if (buf == NULL) 145 return SOC_E_MEMORY; 146 147 lcd_config(unit, devno, NUM_LCD_COLUMNS, NUM_LCD_ROWS); 148 lcd_ttymode(unit, devno); 149 lcd_cls(unit, devno); 150 151 sal_memset(buf,0,128); 152 /* On a 20x4, this should fit across the top */ 153 sal_sprintf(buf, "%s", "Broadcom Corporation\n"); 154 lcd_write(unit, devno, 0, (uint8 *)buf, sal_strlen(buf)); 155 for (i = 0; i < soc_cm_get_num_devices(); i++) { 156 sal_memset(buf,0,128); 157 sal_sprintf(buf, "%d:%s\n", i, soc_dev_name(i)); 158 lcd_write(unit, devno, 0, (uint8 *)buf, sal_strlen(buf)); 159 } 160 161 sal_free(buf); 162 return SOC_E_NONE; 163 } 164 165 /* LCD Driver callout */ 166 i2c_driver_t _soc_i2c_lcd_driver = { 167 0x0, 0x0, /* System assigned bytes */ 168 LCD_DEVICE_TYPE, 169 lcd_read, 170 lcd_write, 171 lcd_ioctl, 172 lcd_init, 173 NULL, 174 };