1 /* 2 * Export Ben NanoNote display operations as a server. 3 * 4 * Copyright (C) 2018 Paul Boddie <paul@boddie.org.uk> 5 * 6 * This program is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU General Public License as 8 * published by the Free Software Foundation; either version 2 of 9 * the License, or (at your option) any later version. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * GNU General Public License for more details. 15 * 16 * You should have received a copy of the GNU General Public License 17 * along with this program; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, 19 * Boston, MA 02110-1301, USA 20 */ 21 22 #include <l4/devices/gpio-jz4740.h> 23 #include <l4/devices/backlight-client.h> 24 #include <l4/devices/lcd-jz4740-config.h> 25 #include <l4/devices/lcd-jz4740-panel.h> 26 #include <l4/devices/memory.h> 27 28 #include <l4/cxx/ipc_server> 29 #include <l4/re/env> 30 #include <l4/re/util/object_registry> 31 #include <l4/sys/capability> 32 33 #include "display-ops.h" 34 35 /* Virtual address for the GPIO register block. */ 36 37 static l4_addr_t gpio_virt_base = 0, gpio_virt_base_end = 0; 38 39 /* GPIO and backlight device abstractions. */ 40 41 static Gpio_jz4740_chip *gpio_port_c = 0; 42 static L4::Cap<Backlight_device_interface> backlight_device; 43 44 45 46 /* GPIO pin definitions. */ 47 48 enum Jz4740_lcd_gpio_mask 49 { 50 Jz4740_lcd_gpio_d0_d7 = 0xff, 51 }; 52 53 enum Jz4740_lcd_gpio 54 { 55 Jz4740_lcd_gpio_clk = 18, /* pixel clock */ 56 Jz4740_lcd_gpio_rs = 19, /* hsync; command/data select */ 57 Jz4740_lcd_gpio_cs = 20, /* vsync; chip select */ 58 }; 59 60 61 62 static int setup_memory(void) 63 { 64 if (get_memory("jz4740-gpio", &gpio_virt_base, &gpio_virt_base_end)) 65 return 1; 66 67 return 0; 68 } 69 70 71 72 /* Display device. */ 73 74 class Display_device_server : public L4::Server_object_t<L4::Kobject> 75 { 76 Pin_slice slcd8_mask = {.offset=0, .mask=(1 << Jz4740_lcd_gpio_cs) | (1 << Jz4740_lcd_gpio_rs) | 77 (1 << Jz4740_lcd_gpio_clk) | Jz4740_lcd_gpio_d0_d7}; 78 79 public: 80 /* Dispatch incoming requests. */ 81 82 int dispatch(l4_umword_t obj, L4::Ipc::Iostream &ios) 83 { 84 l4_msgtag_t tag; 85 86 (void) obj; 87 ios >> tag; 88 89 switch (tag.label()) 90 { 91 case Display_op_disable: 92 disable(); 93 return L4_EOK; 94 95 case Display_op_enable: 96 enable(); 97 return L4_EOK; 98 99 default: 100 return -L4_EBADPROTO; 101 } 102 } 103 104 /* Switch the display off. */ 105 106 void disable(void) 107 { 108 /* Configure SLCD8 pins. */ 109 110 gpio_port_c->multi_setup(slcd8_mask, Hw::Gpio_chip::Input, 0); 111 backlight_device->disable(); 112 } 113 114 /* Switch the display on. */ 115 116 void enable(void) 117 { 118 /* Configure SLCD8 pins. */ 119 120 gpio_port_c->multi_config_pad(slcd8_mask, Hw::Gpio_chip::Function_alt, 0); 121 backlight_device->enable(); 122 } 123 }; 124 125 static L4Re::Util::Registry_server<> server; 126 127 128 129 int main(void) 130 { 131 if (setup_memory()) return 1; 132 133 /* Initialise the GPIO abstraction. */ 134 135 Gpio_jz4740_chip gpio_port(gpio_virt_base + 0x200, gpio_virt_base + 0x300, 32); 136 137 gpio_port_c = &gpio_port; 138 139 /* Obtain a reference to the backlight device. */ 140 141 backlight_device = L4Re::Env::env()->get_cap<Backlight_device_interface>("backlight"); 142 if (!backlight_device.is_valid()) return 1; 143 144 /* Initialise and register a new server object. */ 145 146 Display_device_server server_obj; 147 server.registry()->register_obj(&server_obj, "display"); 148 149 /* Enter the IPC server loop. */ 150 151 server.loop(); 152 return 0; 153 }