diff options
author | Florian Fainelli <florian@openwrt.org> | 2012-11-30 10:53:47 +0000 |
---|---|---|
committer | Florian Fainelli <florian@openwrt.org> | 2012-11-30 10:53:47 +0000 |
commit | 527afd0e9ad14751e4b26c70aa9e9883c839218e (patch) | |
tree | d478bdde0069ca371b27ff57f86cb7e92d1c5cfb /target/linux/ubicom32/files/drivers/video | |
parent | a68f386663f09d3abb315fd8d01e5733547c3005 (diff) | |
download | upstream-527afd0e9ad14751e4b26c70aa9e9883c839218e.tar.gz upstream-527afd0e9ad14751e4b26c70aa9e9883c839218e.tar.bz2 upstream-527afd0e9ad14751e4b26c70aa9e9883c839218e.zip |
remove target
This target is unused, does not support any off the shelf hardware and
has been a maintenance burden for quite some time now.
Signed-off-by: Florian Fainelli <florian@openwrt.org>
SVN-Revision: 34430
Diffstat (limited to 'target/linux/ubicom32/files/drivers/video')
7 files changed, 0 insertions, 3673 deletions
diff --git a/target/linux/ubicom32/files/drivers/video/backlight/ubicom32bl.c b/target/linux/ubicom32/files/drivers/video/backlight/ubicom32bl.c deleted file mode 100644 index 99538c341c..0000000000 --- a/target/linux/ubicom32/files/drivers/video/backlight/ubicom32bl.c +++ /dev/null @@ -1,399 +0,0 @@ -/* - * drivers/video/backlight/ubicom32bl.c - * Backlight driver for the Ubicom32 platform - * - * (C) Copyright 2009, Ubicom, Inc. - * - * This file is part of the Ubicom32 Linux Kernel Port. - * - * The Ubicom32 Linux Kernel Port is free software: you can redistribute - * it and/or modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version 2 of the - * License, or (at your option) any later version. - * - * The Ubicom32 Linux Kernel Port is distributed in the hope that it - * will be useful, but WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - * the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the Ubicom32 Linux Kernel Port. If not, - * see <http://www.gnu.org/licenses/>. - * - * Ubicom32 implementation derived from (with many thanks): - * arch/m68knommu - * arch/blackfin - * arch/parisc - */ -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/backlight.h> -#include <linux/fb.h> - -#include <asm/ubicom32bl.h> -#include <asm/ip5000.h> - -#define DRIVER_NAME "ubicom32bl" -#define UBICOM32BL_MAX_BRIGHTNESS 255 - -struct ubicom32bl_data { - /* - * Pointer to the platform data structure. Keep this around since we need values - * from it to set the backlight intensity. - */ - const struct ubicom32bl_platform_data *pdata; - - /* - * Backlight device, we have to save this for use when we remove ourselves. - */ - struct backlight_device *bldev; - - /* - * Current intensity, used for get_intensity. - */ - int cur_intensity; - - /* - * Init function for PWM - */ - int (*init_fn)(struct ubicom32bl_data *); - - /* - * Set intensity function depending on the backlight type - */ - int (*set_intensity_fn)(struct ubicom32bl_data *, int); -}; - -/* - * ubicom32bl_set_intensity_gpio - */ -static int ubicom32bl_set_intensity_gpio(struct ubicom32bl_data *ud, int intensity) -{ - ud->cur_intensity = intensity ? 255 : 0; - - if (intensity) { - // set gpio - return 0; - } - - // clear gpio - return 0; -} - -/* - * ubicom32bl_set_intensity_hw - */ -static int ubicom32bl_set_intensity_hw(struct ubicom32bl_data *ud, int intensity) -{ - u16_t period = ud->pdata->pwm_period; - u16_t duty; - - /* - * Calculate the new duty cycle - */ - duty = (period * intensity) / (UBICOM32BL_MAX_BRIGHTNESS + 1); - - /* - * Set the new duty cycle - */ - switch (ud->pdata->pwm_channel) { - case 0: - /* - * Channel 0 is in the lower half of PORT C ctl0 and ctl1 - */ - UBICOM32_IO_PORT(RC)->ctl1 = (ud->pdata->pwm_period << 16) | duty; - break; - - case 1: - /* - * Channel 1 is in the upper half of PORT C ctl0 and ctl2 - */ - UBICOM32_IO_PORT(RC)->ctl2 = (ud->pdata->pwm_period << 16) | duty; - break; - - case 2: - /* - * Channel 2 is in PORT H ctl0 and ctl1 - */ - UBICOM32_IO_PORT(RH)->ctl1 = (ud->pdata->pwm_period << 16) | duty; - break; - } - - ud->cur_intensity = intensity; - - return 0; -} - -/* - * ubicom32bl_set_intensity - */ -static int ubicom32bl_set_intensity(struct backlight_device *bd) -{ - struct ubicom32bl_data *ud = (struct ubicom32bl_data *)bl_get_data(bd); - int intensity = bd->props.brightness; - - /* - * If we're blanked the the intensity doesn't matter. - */ - if ((bd->props.power != FB_BLANK_UNBLANK) || (bd->props.fb_blank != FB_BLANK_UNBLANK)) { - intensity = 0; - } - - /* - * Check for inverted backlight. - */ - if (ud->pdata->invert) { - intensity = UBICOM32BL_MAX_BRIGHTNESS - intensity; - } - - if (ud->set_intensity_fn) { - return ud->set_intensity_fn(ud, intensity); - } - - return -ENXIO; -} - -/* - * ubicom32bl_get_intensity - * Return the current intensity of the backlight. - */ -static int ubicom32bl_get_intensity(struct backlight_device *bd) -{ - struct ubicom32bl_data *ud = (struct ubicom32bl_data *)bl_get_data(bd); - - return ud->cur_intensity; -} - -/* - * ubicom32bl_init_hw_pwm - * Set the appropriate PWM registers - */ -static int ubicom32bl_init_hw_pwm(struct ubicom32bl_data *ud) -{ - /* - * bit 13: enable - */ - u16_t pwm_cfg = (1 << 13) | (ud->pdata->pwm_prescale << 8) ; - - switch (ud->pdata->pwm_channel) { - case 0: - /* - * Channel 0 is in the lower half of PORT C ctl0 and ctl1 (PA5) - */ - UBICOM32_IO_PORT(RC)->ctl0 &= ~0xFFFF; - UBICOM32_IO_PORT(RC)->ctl0 |= pwm_cfg; - UBICOM32_IO_PORT(RC)->ctl1 = ud->pdata->pwm_period << 16; - - /* - * If the port function is not set, set it to GPIO/PWM - */ - if (!UBICOM32_IO_PORT(RA)->function) { - UBICOM32_IO_PORT(RA)->function = 3; - } - break; - - case 1: - /* - * Channel 1 is in the upper half of PORT C ctl0 and ctl2 (PE4) - */ - UBICOM32_IO_PORT(RC)->ctl0 &= ~0xFFFF0000; - UBICOM32_IO_PORT(RC)->ctl0 |= (pwm_cfg << 16); - UBICOM32_IO_PORT(RC)->ctl2 = ud->pdata->pwm_period << 16; - - /* - * If the port function is not set, set it to GPIO/ExtIOInt - */ - if (!UBICOM32_IO_PORT(RE)->function) { - UBICOM32_IO_PORT(RE)->function = 3; - } - break; - - case 2: - /* - * Channel 2 is in PORT H ctl0 and ctl1 (PD0) - */ - UBICOM32_IO_PORT(RH)->ctl0 &= ~0xFFFF0000; - UBICOM32_IO_PORT(RH)->ctl0 = pwm_cfg; - UBICOM32_IO_PORT(RH)->ctl1 = ud->pdata->pwm_period << 16; - - /* - * If the port function is not set, set it to GPIO - */ - if (!UBICOM32_IO_PORT(RD)->function) { - UBICOM32_IO_PORT(RD)->function = 3; - } - break; - } - - return 0; -} - -/* - * ubicom32bl_init_gpio - * Allocate the appropriate GPIO - */ -static int ubicom32bl_init_gpio(struct ubicom32bl_data *ud) -{ - return 0; -} - -static struct backlight_ops ubicom32bl_ops = { - .get_brightness = ubicom32bl_get_intensity, - .update_status = ubicom32bl_set_intensity, -}; - -/* - * ubicom32bl_probe - */ -static int ubicom32bl_probe(struct platform_device *pdev) -{ - const struct ubicom32bl_platform_data *pdata = pdev->dev.platform_data; - struct ubicom32bl_data *ud; - struct backlight_device *bldev; - int retval; - - /* - * Check to see if we have any platform data, if we don't then the backlight is not - * configured on this device. - */ - if (!pdata) { - return -ENODEV; - } - - /* - * Allocate our private data - */ - ud = kzalloc(sizeof(struct ubicom32bl_data), GFP_KERNEL); - if (!ud) { - return -ENOMEM; - } - - ud->pdata = pdata; - - /* - * Check to see that the platform data is valid for this driver - */ - switch (pdata->type) { - case UBICOM32BL_TYPE_PWM: - { - /* - * Make sure we have a PWM peripheral - */ - u32_t chipid; - asm volatile ( - "move.4 %0, CHIP_ID \n\t" - : "=r" (chipid) - ); - if (chipid != 0x00030001) { - retval = -ENODEV; - goto fail; - } - - if (pdata->pwm_channel > 3) { - retval = -ENODEV; - goto fail; - } - if (pdata->pwm_prescale > 16) { - retval = -EINVAL; - goto fail; - } - - ud->init_fn = ubicom32bl_init_hw_pwm; - ud->set_intensity_fn = ubicom32bl_set_intensity_hw; - break; - } - - case UBICOM32BL_TYPE_PWM_HRT: - // For now, PWM HRT devices are treated as binary lights. - - case UBICOM32BL_TYPE_BINARY: - ud->init_fn = ubicom32bl_init_gpio; - ud->set_intensity_fn = ubicom32bl_set_intensity_gpio; - break; - } - - /* - * Register our backlight device - */ - bldev = backlight_device_register(DRIVER_NAME, &pdev->dev, ud, &ubicom32bl_ops); - if (IS_ERR(bldev)) { - retval = PTR_ERR(bldev); - goto fail; - } - - ud->bldev = bldev; - ud->cur_intensity = pdata->default_intensity; - platform_set_drvdata(pdev, ud); - - /* - * Start up the backlight at the prescribed default intensity - */ - bldev->props.power = FB_BLANK_UNBLANK; - bldev->props.max_brightness = UBICOM32BL_MAX_BRIGHTNESS; - bldev->props.brightness = pdata->default_intensity; - - if (ud->init_fn) { - if (ud->init_fn(ud) != 0) { - retval = -ENODEV; - backlight_device_unregister(ud->bldev); - goto fail; - } - } - ubicom32bl_set_intensity(bldev); - - printk(KERN_INFO DRIVER_NAME ": Backlight driver started\n"); - - return 0; - -fail: - platform_set_drvdata(pdev, NULL); - kfree(ud); - return retval; -} - -/* - * ubicom32bl_remove - */ -static int __exit ubicom32bl_remove(struct platform_device *pdev) -{ - struct ubicom32bl_data *ud = platform_get_drvdata(pdev); - - backlight_device_unregister(ud->bldev); - platform_set_drvdata(pdev, NULL); - kfree(ud); - - return 0; -} - -static struct platform_driver ubicom32bl_driver = { - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE, - }, - - .remove = __exit_p(ubicom32bl_remove), -}; - -/* - * ubicom32bl_init - */ -static int __init ubicom32bl_init(void) -{ - return platform_driver_probe(&ubicom32bl_driver, ubicom32bl_probe); -} -module_init(ubicom32bl_init); - -/* - * ubicom32bl_exit - */ -static void __exit ubicom32bl_exit(void) -{ - platform_driver_unregister(&ubicom32bl_driver); -} -module_exit(ubicom32bl_exit); - -MODULE_AUTHOR("Patrick Tjin <@ubicom.com>"); -MODULE_DESCRIPTION("Ubicom32 backlight driver"); -MODULE_LICENSE("GPL"); diff --git a/target/linux/ubicom32/files/drivers/video/backlight/ubicom32lcd.c b/target/linux/ubicom32/files/drivers/video/backlight/ubicom32lcd.c deleted file mode 100644 index e4f8c713e0..0000000000 --- a/target/linux/ubicom32/files/drivers/video/backlight/ubicom32lcd.c +++ /dev/null @@ -1,372 +0,0 @@ -/* - * drivers/video/ubicom32lcd.c - * LCD initilization code - * - * (C) Copyright 2009, Ubicom, Inc. - * - * This file is part of the Ubicom32 Linux Kernel Port. - * - * The Ubicom32 Linux Kernel Port is free software: you can redistribute - * it and/or modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version 2 of the - * License, or (at your option) any later version. - * - * The Ubicom32 Linux Kernel Port is distributed in the hope that it - * will be useful, but WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - * the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the Ubicom32 Linux Kernel Port. If not, - * see <http://www.gnu.org/licenses/>. - */ -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/delay.h> - -#include <asm/ip5000.h> -#include <asm/gpio.h> -#include <asm/ubicom32lcd.h> - -#include "ubicom32lcd.h" - -#define DRIVER_NAME "ubicom32lcd" - -struct ubicom32lcd_data { - const struct ubicom32lcd_panel *panel; - - int pin_cs; - int pin_rd; - int pin_rs; - int pin_wr; - int pin_reset; - struct ubicom32_io_port *port_data; - int data_shift; -}; - -/* - * ubicom32lcd_write - * Performs a write cycle on the bus (assumes CS asserted, RD & WR set) - */ -static void ubicom32lcd_write(struct ubicom32lcd_data *ud, int command, u16 data) -{ - if (command) { - UBICOM32_GPIO_SET_PIN_LOW(ud->pin_rs); - } else { - UBICOM32_GPIO_SET_PIN_HIGH(ud->pin_rs); - } - - asm volatile ( - "or.4 4(%[port]), 4(%[port]), %[mask] \n\t" - "not.4 %[mask], %[mask] \n\t" - "and.4 8(%[port]), 8(%[port]), %[mask] \n\t" - "or.4 8(%[port]), 8(%[port]), %[cmd] \n\t" - : - : [port] "a" (ud->port_data), - [mask] "d" (0xFFFF << ud->data_shift), - [cmd] "d" (data << ud->data_shift) - : "cc" - ); - - UBICOM32_GPIO_SET_PIN_LOW(ud->pin_wr); - - //ndelay(50); - udelay(1); - - UBICOM32_GPIO_SET_PIN_HIGH(ud->pin_wr); - - udelay(1); - //ndelay(50); -} - -/* - * ubicom32lcd_read_data - * Performs a read cycle on the bus (assumes CS asserted, RD & WR set) - */ -static u16 ubicom32lcd_read_data(struct ubicom32lcd_data *ud) -{ - u32_t data; - - UBICOM32_GPIO_SET_PIN_HIGH(ud->pin_rs); - - asm volatile ( - "and.4 4(%[port]), 4(%[port]), %[mask]\n\t" - : - : [port] "a" (ud->port_data), - [mask] "d" (~(0xFFFF << ud->data_shift)) - : "cc" - ); - - UBICOM32_GPIO_SET_PIN_LOW(ud->pin_rd); - - ndelay(300); - - asm volatile ( - "lsr.4 %[data], 12(%[port]), %[shamt] \n\t" - "and.4 %[data], %[data], %[mask] \n\t" - : [data] "=d" (data) - : [port] "a" (ud->port_data), - [mask] "d" (0xFFFF), - [shamt] "d" (ud->data_shift) - : "cc" - ); - - ndelay(200); - - UBICOM32_GPIO_SET_PIN_HIGH(ud->pin_rd); - - ndelay(500); - - return data; -} - -/* - * ubicom32lcd_execute - * Executes a script for performing operations on the LCD (assumes CS set) - */ -static void ubicom32lcd_execute(struct ubicom32lcd_data *ud, const struct ubicom32lcd_step *script) -{ - while (1) { - switch (script->op) { - case LCD_STEP_CMD: - ubicom32lcd_write(ud, 1, script->cmd); - break; - - case LCD_STEP_DATA: - ubicom32lcd_write(ud, 0, script->data); - break; - - case LCD_STEP_CMD_DATA: - ubicom32lcd_write(ud, 1, script->cmd); - ubicom32lcd_write(ud, 0, script->data); - break; - - case LCD_STEP_SLEEP: - udelay(script->data); - break; - - case LCD_STEP_DONE: - return; - } - script++; - } -} - -/* - * ubicom32lcd_goto - * Places the gram pointer at a specific X, Y address - */ -static void ubicom32lcd_goto(struct ubicom32lcd_data *ud, int x, int y) -{ - ubicom32lcd_write(ud, 1, ud->panel->horz_reg); - ubicom32lcd_write(ud, 0, x); - ubicom32lcd_write(ud, 1, ud->panel->vert_reg); - ubicom32lcd_write(ud, 0, y); - ubicom32lcd_write(ud, 1, ud->panel->gram_reg); -} - -/* - * ubicom32lcd_panel_init - * Initializes the lcd panel. - */ -static int ubicom32lcd_panel_init(struct ubicom32lcd_data *ud) -{ - u16 id; - - UBICOM32_GPIO_SET_PIN_LOW(ud->pin_reset); - UBICOM32_GPIO_SET_PIN_OUTPUT(ud->pin_reset); - UBICOM32_GPIO_ENABLE(ud->pin_reset); - - asm volatile ( - "or.4 0x50(%[port]), 0x50(%[port]), %[mask] \n\t" - "not.4 %[mask], %[mask] \n\t" - "and.4 0x04(%[port]), 0x04(%[port]), %[mask] \n\t" - : - : [port] "a" (ud->port_data), - [mask] "d" (0xFFFF << ud->data_shift) - : "cc" - ); - - UBICOM32_GPIO_SET_PIN_HIGH(ud->pin_rs); - UBICOM32_GPIO_SET_PIN_HIGH(ud->pin_rd); - UBICOM32_GPIO_SET_PIN_HIGH(ud->pin_wr); - UBICOM32_GPIO_SET_PIN_HIGH(ud->pin_cs); - - UBICOM32_GPIO_SET_PIN_OUTPUT(ud->pin_rs); - UBICOM32_GPIO_SET_PIN_OUTPUT(ud->pin_rd); - UBICOM32_GPIO_SET_PIN_OUTPUT(ud->pin_wr); - UBICOM32_GPIO_SET_PIN_OUTPUT(ud->pin_cs); - - UBICOM32_GPIO_ENABLE(ud->pin_rs); - UBICOM32_GPIO_ENABLE(ud->pin_rd); - UBICOM32_GPIO_ENABLE(ud->pin_wr); - UBICOM32_GPIO_ENABLE(ud->pin_cs); - - udelay(20); - - UBICOM32_GPIO_SET_PIN_HIGH(ud->pin_reset); - - udelay(20); - - UBICOM32_GPIO_SET_PIN_LOW(ud->pin_cs); - - id = ubicom32lcd_read_data(ud); - - /* - * We will try to figure out what kind of panel we have if we were not told. - */ - if (!ud->panel) { - const struct ubicom32lcd_panel **p = ubicom32lcd_panels; - while (*p) { - if ((*p)->id && ((*p)->id == id)) { - break; - } - p++; - } - if (!*p) { - printk(KERN_WARNING DRIVER_NAME ":Could not find compatible panel, id=%x\n", id); - return -ENODEV; - } - ud->panel = *p; - } - - /* - * Make sure panel ID matches if we were supplied a panel type - */ - if (ud->panel->id && (ud->panel->id != id)) { - UBICOM32_GPIO_SET_PIN_HIGH(ud->pin_cs); - - return -ENODEV; - } - - ubicom32lcd_execute(ud, ud->panel->init_seq); - - ubicom32lcd_goto(ud, 0, 0); - - UBICOM32_GPIO_SET_PIN_HIGH(ud->pin_cs); - UBICOM32_GPIO_SET_PIN_HIGH(ud->pin_rd); - UBICOM32_GPIO_SET_PIN_HIGH(ud->pin_wr); - UBICOM32_GPIO_SET_PIN_HIGH(ud->pin_rs); - - printk(KERN_INFO DRIVER_NAME ": Initialized panel %s\n", ud->panel->desc); - - return 0; -} - -/* - * ubicom32lcd_probe - */ -static int ubicom32lcd_probe(struct platform_device *pdev) -{ - const struct ubicom32lcd_platform_data *pdata = pdev->dev.platform_data; - struct ubicom32lcd_data *ud; - int retval; - - /* - * Allocate our private data - */ - ud = kzalloc(sizeof(struct ubicom32lcd_data), GFP_KERNEL); - if (!ud) { - return -ENOMEM; - } - - if (pdata) { - ud->pin_cs = pdata->pin_cs; - ud->pin_rd = pdata->pin_rd; - ud->pin_wr = pdata->pin_wr; - ud->pin_rs = pdata->pin_rs; - ud->pin_reset = pdata->pin_reset; - ud->port_data = pdata->port_data; - ud->data_shift = pdata->data_shift; - } else { - /* - * Defaults - */ - ud->pin_cs = GPIO_RD_4; - ud->pin_rd = GPIO_RD_5; - ud->pin_rs = GPIO_RD_3; - ud->pin_wr = GPIO_RD_2; - ud->pin_reset = GPIO_RD_7; - ud->port_data = (struct ubicom32_io_port *)RI; - ud->data_shift = 0; - } - - /* - * Initialize the display - */ - retval = ubicom32lcd_panel_init(ud); - if (retval) { - kfree(ud); - return retval; - } - - printk(KERN_INFO DRIVER_NAME ": LCD initialized\n"); - - return 0; -} - -/* - * ubicom32lcd_remove - */ -static int __exit ubicom32lcd_remove(struct platform_device *pdev) -{ - struct ubicom32lcd_data *ud = platform_get_drvdata(pdev); - - kfree(ud); - - return 0; -} - -static struct platform_driver ubicom32lcd_driver = { - .probe = ubicom32lcd_probe, - .remove = ubicom32lcd_remove, - - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE, - }, - - .remove = __exit_p(ubicom32lcd_remove), -}; - -static struct platform_device *ubicom32lcd_device; - -/* - * ubicom32lcd_init - */ -static int __init ubicom32lcd_init(void) -{ - int res; - - res = platform_driver_register(&ubicom32lcd_driver); - if (res == 0) { - ubicom32lcd_device = platform_device_alloc(DRIVER_NAME, 0); - if (ubicom32lcd_device) { - res = platform_device_add(ubicom32lcd_device); - } else { - res = -ENOMEM; - } - if (res) { - platform_device_put(ubicom32lcd_device); - platform_driver_unregister(&ubicom32lcd_driver); - } - } - return res; -} -module_init(ubicom32lcd_init); - -/* - * ubicom32lcd_exit - */ -static void __exit ubicom32lcd_exit(void) -{ - platform_device_unregister(ubicom32lcd_device); - platform_driver_unregister(&ubicom32lcd_driver); -} -module_exit(ubicom32lcd_exit); - -MODULE_AUTHOR("Patrick Tjin <@ubicom.com>"); -MODULE_DESCRIPTION("Ubicom32 LCD driver"); -MODULE_LICENSE("GPL"); diff --git a/target/linux/ubicom32/files/drivers/video/backlight/ubicom32lcd.h b/target/linux/ubicom32/files/drivers/video/backlight/ubicom32lcd.h deleted file mode 100644 index 07650ba9e3..0000000000 --- a/target/linux/ubicom32/files/drivers/video/backlight/ubicom32lcd.h +++ /dev/null @@ -1,546 +0,0 @@ -/* - * ubicom32lcd.h - * Ubicom32 lcd panel drivers - * - * (C) Copyright 2009, Ubicom, Inc. - * - * This file is part of the Ubicom32 Linux Kernel Port. - * - * This Ubicom32 library is free software: you can redistribute - * it and/or modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version 2 of the - * License, or (at your option) any later version. - * - * This Ubicom32 library is distributed in the hope that it - * will be useful, but WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - * the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the Ubicom32 Linux Kernel Port. If not, - * see <http://www.gnu.org/licenses/>. - */ - -#ifndef _UBICOM32LCD_H_ -#define _UBICOM32LCD_H_ - -enum ubicom32lcd_op { - /* - * Sleep for (data) ms - */ - LCD_STEP_SLEEP, - - /* - * Execute write of command - */ - LCD_STEP_CMD, - - /* - * Execute write of data - */ - LCD_STEP_DATA, - - /* - * Execute write of command/data - */ - LCD_STEP_CMD_DATA, - - /* - * Script done - */ - LCD_STEP_DONE, -}; - -struct ubicom32lcd_step { - enum ubicom32lcd_op op; - u16 cmd; - u16 data; -}; - -struct ubicom32lcd_panel { - const struct ubicom32lcd_step *init_seq; - const char *desc; - - u32 xres; - u32 yres; - u32 stride; - u32 flags; - - u16 id; - u16 horz_reg; - u16 vert_reg; - u16 gram_reg; -}; - -#ifdef CONFIG_LCD_UBICOM32_CFAF240320KTTS -static const struct ubicom32lcd_step cfaf240320ktts_init_0[] = { - {LCD_STEP_CMD_DATA, 0x0001, 0x0000,}, // Driver Output Control Register (R01h) Page 14, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0002, 0x0700,}, // LCD Driving Waveform Control (R02h) Page 15, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0003, 0x50A0,}, // Entry Mode (R03h) 0 degrees - {LCD_STEP_CMD_DATA, 0x0004, 0x0000,}, // Scaling Control register (R04h) Page 16, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0008, 0x0207,}, // Display Control 2 (R08h) Page 17, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0009, 0x0000,}, // Display Control 3 (R09h) Page 18, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x000A, 0x0000,}, // Frame Cycle Control (R0Ah) Page 19, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x000C, 0x0000,}, // External Display Interface Control 1 (R0Ch) Page 20, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x000D, 0x0000,}, // Frame Maker Position (R0Dh) Page 21, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x000F, 0x0000,}, // External Display Interface Control 2 (R0Fh) Page 21, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0010, 0x0000,}, // Power Control 1 (R10h) Page 22, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0011, 0x0007,}, // Power Control 2 (R11h) Page 23, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0012, 0x0000,}, // Power Control 3 (R12h) Page 24, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0013, 0x0000,}, // Power Control 4 (R13h) Page 25, SPFD5408B Datasheet - {LCD_STEP_SLEEP, 0, 200}, - {LCD_STEP_CMD_DATA, 0x0007, 0x0101,}, // Display Control (R07h) Page 16, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0010, 0x12B0,}, // Power Control 1 (R10h) Page 22, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0011, 0x0007,}, // Power Control 2 (R11h) Page 23, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0012, 0x01BB,}, // Power Control 3 (R12h) Page 24, SPFD5408B Datasheet - {LCD_STEP_SLEEP, 0, 50}, - {LCD_STEP_CMD_DATA, 0x0013, 0x1300,}, // Power Control 4 (R13h) Page 25, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0029, 0x0010,}, // NVM read data 2 (R29h) Page 30, SPFD5408B Datasheet - {LCD_STEP_SLEEP, 0, 50}, - {LCD_STEP_CMD_DATA, 0x0030, 0x000A,}, // Gamma Control 1 Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0031, 0x1326,}, // Gamma Control 2 Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0032, 0x0A29,}, // Gamma Control 3 Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0033, 0x290A,}, // Gamma Control 4 Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0034, 0x2613,}, // Gamma Control 5 Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0035, 0x0A0A,}, // Gamma Control 6 Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0036, 0x1E03,}, // Gamma Control 7 Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0037, 0x031E,}, // Gamma Control 8 Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0038, 0x0706,}, // Gamma Control 9 Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0039, 0x0303,}, // Gamma Control 10 Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x003A, 0x0E04,}, // Gamma Control 11 Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x003B, 0x0E01,}, // Gamma Control 12 Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x003C, 0x010E,}, // Gamma Control 13 Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x003D, 0x040E,}, // Gamma Control 14 Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x003E, 0x0303,}, // Gamma Control 15 Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x003F, 0x0607,}, // Gamma Control 16 Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0050, 0x0000,}, // Window Horizontal RAM Address Start (R50h) Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0051, 0x00EF,}, // Window Horizontal RAM Address End (R51h) Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0052, 0x0000,}, // Window Vertical RAM Address Start (R52h) Page 33, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0053, 0x013F,}, // Window Vertical RAM Address End (R53h) Page 33, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0060, 0x2700,}, // Driver Output Control (R60h) Page 33, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0061, 0x0001,}, // Driver Output Control (R61h) Page 35, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x006A, 0x0000,}, // Vertical Scroll Control (R6Ah) Page 35, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0080, 0x0000,}, // Display Position - Partial Display 1 (R80h) Page 35, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0081, 0x0000,}, // RAM Address Start - Partial Display 1 (R81h) Page 35, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0082, 0x0000,}, // RAM Address End - Partial Display 1 (R82h) Page 36, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0083, 0x0000,}, // Display Position - Partial Display 2 (R83h) Page 36, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0084, 0x0000,}, // RAM Address Start - Partial Display 2 (R84h) Page 36, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0085, 0x0000,}, // RAM Address End - Partial Display 2 (R85h) Page 36, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0090, 0x0010,}, // Panel Interface Control 1 (R90h) Page 36, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0092, 0x0000,}, // Panel Interface Control 2 (R92h) Page 37, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0093, 0x0103,}, // Panel Interface control 3 (R93h) Page 38, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0095, 0x0210,}, // Panel Interface control 4 (R95h) Page 38, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0097, 0x0000,}, // Panel Interface Control 5 (R97h) Page 40, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0098, 0x0000,}, // Panel Interface Control 6 (R98h) Page 41, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0007, 0x0173,}, // Display Control (R07h) Page 16, SPFD5408B Datasheet - {LCD_STEP_DONE, 0, 0}, -}; - -const struct ubicom32lcd_panel cfaf240320ktts_0 = { - .desc = "CFAF240320KTTS", - .init_seq = cfaf240320ktts_init_0, - .horz_reg = 0x20, - .vert_reg = 0x21, - .gram_reg = 0x22, - .xres = 240, - .yres = 320, - .stride = 240, - .id = 0x5408, -}; -#endif - -#ifdef CONFIG_LCD_UBICOM32_CFAF240320KTTS_180 -static const struct ubicom32lcd_step cfaf240320ktts_init_180[] = { - {LCD_STEP_CMD_DATA, 0x0001, 0x0000,}, // Driver Output Control Register (R01h) Page 14, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0002, 0x0700,}, // LCD Driving Waveform Control (R02h) Page 15, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0003, 0x5000,}, // Entry Mode (R03h) 180 degrees - {LCD_STEP_CMD_DATA, 0x0004, 0x0000,}, // Scaling Control register (R04h) Page 16, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0008, 0x0207,}, // Display Control 2 (R08h) Page 17, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0009, 0x0000,}, // Display Control 3 (R09h) Page 18, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x000A, 0x0000,}, // Frame Cycle Control (R0Ah) Page 19, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x000C, 0x0000,}, // External Display Interface Control 1 (R0Ch) Page 20, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x000D, 0x0000,}, // Frame Maker Position (R0Dh) Page 21, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x000F, 0x0000,}, // External Display Interface Control 2 (R0Fh) Page 21, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0010, 0x0000,}, // Power Control 1 (R10h) Page 22, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0011, 0x0007,}, // Power Control 2 (R11h) Page 23, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0012, 0x0000,}, // Power Control 3 (R12h) Page 24, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0013, 0x0000,}, // Power Control 4 (R13h) Page 25, SPFD5408B Datasheet - {LCD_STEP_SLEEP, 0, 200}, - {LCD_STEP_CMD_DATA, 0x0007, 0x0101,}, // Display Control (R07h) Page 16, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0010, 0x12B0,}, // Power Control 1 (R10h) Page 22, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0011, 0x0007,}, // Power Control 2 (R11h) Page 23, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0012, 0x01BB,}, // Power Control 3 (R12h) Page 24, SPFD5408B Datasheet - {LCD_STEP_SLEEP, 0, 50}, - {LCD_STEP_CMD_DATA, 0x0013, 0x1300,}, // Power Control 4 (R13h) Page 25, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0029, 0x0010,}, // NVM read data 2 (R29h) Page 30, SPFD5408B Datasheet - {LCD_STEP_SLEEP, 0, 50}, - {LCD_STEP_CMD_DATA, 0x0030, 0x000A,}, // Gamma Control 1 Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0031, 0x1326,}, // Gamma Control 2 Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0032, 0x0A29,}, // Gamma Control 3 Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0033, 0x290A,}, // Gamma Control 4 Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0034, 0x2613,}, // Gamma Control 5 Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0035, 0x0A0A,}, // Gamma Control 6 Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0036, 0x1E03,}, // Gamma Control 7 Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0037, 0x031E,}, // Gamma Control 8 Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0038, 0x0706,}, // Gamma Control 9 Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0039, 0x0303,}, // Gamma Control 10 Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x003A, 0x0E04,}, // Gamma Control 11 Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x003B, 0x0E01,}, // Gamma Control 12 Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x003C, 0x010E,}, // Gamma Control 13 Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x003D, 0x040E,}, // Gamma Control 14 Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x003E, 0x0303,}, // Gamma Control 15 Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x003F, 0x0607,}, // Gamma Control 16 Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0050, 0x0000,}, // Window Horizontal RAM Address Start (R50h) Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0051, 0x00EF,}, // Window Horizontal RAM Address End (R51h) Page 32, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0052, 0x0000,}, // Window Vertical RAM Address Start (R52h) Page 33, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0053, 0x013F,}, // Window Vertical RAM Address End (R53h) Page 33, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0060, 0x2700,}, // Driver Output Control (R60h) Page 33, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0061, 0x0001,}, // Driver Output Control (R61h) Page 35, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x006A, 0x0000,}, // Vertical Scroll Control (R6Ah) Page 35, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0080, 0x0000,}, // Display Position - Partial Display 1 (R80h) Page 35, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0081, 0x0000,}, // RAM Address Start - Partial Display 1 (R81h) Page 35, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0082, 0x0000,}, // RAM Address End - Partial Display 1 (R82h) Page 36, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0083, 0x0000,}, // Display Position - Partial Display 2 (R83h) Page 36, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0084, 0x0000,}, // RAM Address Start - Partial Display 2 (R84h) Page 36, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0085, 0x0000,}, // RAM Address End - Partial Display 2 (R85h) Page 36, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0090, 0x0010,}, // Panel Interface Control 1 (R90h) Page 36, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0092, 0x0000,}, // Panel Interface Control 2 (R92h) Page 37, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0093, 0x0103,}, // Panel Interface control 3 (R93h) Page 38, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0095, 0x0210,}, // Panel Interface control 4 (R95h) Page 38, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0097, 0x0000,}, // Panel Interface Control 5 (R97h) Page 40, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0098, 0x0000,}, // Panel Interface Control 6 (R98h) Page 41, SPFD5408B Datasheet - {LCD_STEP_CMD_DATA, 0x0007, 0x0173,}, // Display Control (R07h) Page 16, SPFD5408B Datasheet - {LCD_STEP_DONE, 0, 0}, -}; - -const struct ubicom32lcd_panel cfaf240320ktts_180 = { - .desc = "CFAF240320KTTS 180", - .init_seq = cfaf240320ktts_init_180, - .horz_reg = 0x20, - .vert_reg = 0x21, - .gram_reg = 0x22, - .xres = 240, - .yres = 320, - .stride = 240, - .id = 0x5408, -}; -#endif - -#ifdef CONFIG_LCD_UBICOM32_TFT2N0369E_P -static const struct ubicom32lcd_step tft2n0369ep_init[] = { - {LCD_STEP_CMD_DATA, 0x0028, 0x0006}, - {LCD_STEP_CMD_DATA, 0x0000, 0x0001}, - {LCD_STEP_SLEEP, 0, 15}, - {LCD_STEP_CMD_DATA, 0x002B, 0x9532}, - {LCD_STEP_CMD_DATA, 0x0003, 0xAAAC}, - {LCD_STEP_CMD_DATA, 0x000C, 0x0002}, - {LCD_STEP_CMD_DATA, 0x000D, 0x000A}, - {LCD_STEP_CMD_DATA, 0x000E, 0x2C00}, - {LCD_STEP_CMD_DATA, 0x001E, 0x00AA}, - {LCD_STEP_CMD_DATA, 0x0025, 0x8000}, - {LCD_STEP_SLEEP, 0, 15}, - {LCD_STEP_CMD_DATA, 0x0001, 0x2B3F}, - {LCD_STEP_CMD_DATA, 0x0002, 0x0600}, - {LCD_STEP_CMD_DATA, 0x0010, 0x0000}, - {LCD_STEP_CMD_DATA, 0x0011, 0x6030}, - {LCD_STEP_SLEEP, 0, 20}, - {LCD_STEP_CMD_DATA, 0x0005, 0x0000}, - {LCD_STEP_CMD_DATA, 0x0006, 0x0000}, - {LCD_STEP_CMD_DATA, 0x0016, 0xEF1C}, - {LCD_STEP_CMD_DATA, 0x0017, 0x0003}, - {LCD_STEP_CMD_DATA, 0x0007, 0x0233}, - {LCD_STEP_CMD_DATA, 0x000B, 0x5312}, - {LCD_STEP_CMD_DATA, 0x000F, 0x0000}, - {LCD_STEP_SLEEP, 0, 20}, - {LCD_STEP_CMD_DATA, 0x0041, 0x0000}, - {LCD_STEP_CMD_DATA, 0x0042, 0x0000}, - {LCD_STEP_CMD_DATA, 0x0048, 0x0000}, - {LCD_STEP_CMD_DATA, 0x0049, 0x013F}, - {LCD_STEP_CMD_DATA, 0x0044, 0xEF00}, - {LCD_STEP_CMD_DATA, 0x0045, 0x0000}, - {LCD_STEP_CMD_DATA, 0x0046, 0x013F}, - {LCD_STEP_CMD_DATA, 0x004A, 0x0000}, - {LCD_STEP_CMD_DATA, 0x004B, 0x0000}, - {LCD_STEP_SLEEP, 0, 20}, - {LCD_STEP_CMD_DATA, 0x0030, 0x0707}, - {LCD_STEP_CMD_DATA, 0x0031, 0x0704}, - {LCD_STEP_CMD_DATA, 0x0032, 0x0204}, - {LCD_STEP_CMD_DATA, 0x0033, 0x0201}, - {LCD_STEP_CMD_DATA, 0x0034, 0x0203}, - {LCD_STEP_CMD_DATA, 0x0035, 0x0204}, - {LCD_STEP_CMD_DATA, 0x0036, 0x0204}, - {LCD_STEP_CMD_DATA, 0x0037, 0x0502}, - {LCD_STEP_CMD_DATA, 0x003A, 0x0302}, - {LCD_STEP_CMD_DATA, 0x003B, 0x0500}, - {LCD_STEP_SLEEP, 0, 20}, - {LCD_STEP_CMD_DATA, 0x0044, 239 << 8 | 0}, - {LCD_STEP_CMD_DATA, 0x0045, 0x0000}, - {LCD_STEP_CMD_DATA, 0x0046, 319}, - {LCD_STEP_DONE, 0, 0}, -}; - -const struct ubicom32lcd_panel tft2n0369ep = { - .desc = "TFT2N0369E-Portrait", - .init_seq = tft2n0369ep_init, - .horz_reg = 0x4e, - .vert_reg = 0x4f, - .gram_reg = 0x22, - .xres = 240, - .yres = 320, - .stride = 240, - .id = 0x8989, -}; -#endif - -#ifdef CONFIG_LCD_UBICOM32_TFT2N0369E_L -static const struct ubicom32lcd_step tft2n0369e_init[] = { - {LCD_STEP_CMD_DATA, 0x0028, 0x0006}, - {LCD_STEP_CMD_DATA, 0x0000, 0x0001}, - {LCD_STEP_SLEEP, 0, 15}, - {LCD_STEP_CMD_DATA, 0x002B, 0x9532}, - {LCD_STEP_CMD_DATA, 0x0003, 0xAAAC}, - {LCD_STEP_CMD_DATA, 0x000C, 0x0002}, - {LCD_STEP_CMD_DATA, 0x000D, 0x000A}, - {LCD_STEP_CMD_DATA, 0x000E, 0x2C00}, - {LCD_STEP_CMD_DATA, 0x001E, 0x00AA}, - {LCD_STEP_CMD_DATA, 0x0025, 0x8000}, - {LCD_STEP_SLEEP, 0, 15}, - {LCD_STEP_CMD_DATA, 0x0001, 0x2B3F}, - {LCD_STEP_CMD_DATA, 0x0002, 0x0600}, - {LCD_STEP_CMD_DATA, 0x0010, 0x0000}, - {LCD_STEP_CMD_DATA, 0x0011, 0x60A8}, - {LCD_STEP_SLEEP, 0, 20}, - {LCD_STEP_CMD_DATA, 0x0005, 0x0000}, - {LCD_STEP_CMD_DATA, 0x0006, 0x0000}, - {LCD_STEP_CMD_DATA, 0x0016, 0xEF1C}, - {LCD_STEP_CMD_DATA, 0x0017, 0x0003}, - {LCD_STEP_CMD_DATA, 0x0007, 0x0233}, - {LCD_STEP_CMD_DATA, 0x000B, 0x5312}, - {LCD_STEP_CMD_DATA, 0x000F, 0x0000}, - {LCD_STEP_SLEEP, 0, 20}, - {LCD_STEP_CMD_DATA, 0x0041, 0x0000}, - {LCD_STEP_CMD_DATA, 0x0042, 0x0000}, - {LCD_STEP_CMD_DATA, 0x0048, 0x0000}, - {LCD_STEP_CMD_DATA, 0x0049, 0x013F}, - {LCD_STEP_CMD_DATA, 0x0044, 0xEF00}, - {LCD_STEP_CMD_DATA, 0x0045, 0x0000}, - {LCD_STEP_CMD_DATA, 0x0046, 0x013F}, - {LCD_STEP_CMD_DATA, 0x004A, 0x0000}, - {LCD_STEP_CMD_DATA, 0x004B, 0x0000}, - {LCD_STEP_SLEEP, 0, 20}, - {LCD_STEP_CMD_DATA, 0x0030, 0x0707}, - {LCD_STEP_CMD_DATA, 0x0031, 0x0704}, - {LCD_STEP_CMD_DATA, 0x0032, 0x0204}, - {LCD_STEP_CMD_DATA, 0x0033, 0x0201}, - {LCD_STEP_CMD_DATA, 0x0034, 0x0203}, - {LCD_STEP_CMD_DATA, 0x0035, 0x0204}, - {LCD_STEP_CMD_DATA, 0x0036, 0x0204}, - {LCD_STEP_CMD_DATA, 0x0037, 0x0502}, - {LCD_STEP_CMD_DATA, 0x003A, 0x0302}, - {LCD_STEP_CMD_DATA, 0x003B, 0x0500}, - {LCD_STEP_SLEEP, 0, 20}, - {LCD_STEP_CMD_DATA, 0x0044, 239 << 8 | 0}, - {LCD_STEP_CMD_DATA, 0x0045, 0x0000}, - {LCD_STEP_CMD_DATA, 0x0046, 319}, - {LCD_STEP_DONE, 0, 0}, -}; - -const struct ubicom32lcd_panel tft2n0369e = { - .desc = "TFT2N0369E-Landscape", - .init_seq = tft2n0369e_init, - .horz_reg = 0x4e, - .vert_reg = 0x4f, - .gram_reg = 0x22, - .xres = 320, - .yres = 240, - .stride = 320, - .id = 0x8989, -}; -#endif - -#ifdef CONFIG_LCD_UBICOM32_CFAF240400D -static const struct ubicom32lcd_step cfaf240400d_init[] = { - {LCD_STEP_CMD_DATA, 0x0606, 0x0000}, // Pin Control (R606h) // Page 41 of SPFD5420A Datasheet - {LCD_STEP_SLEEP, 0, 50}, - {LCD_STEP_CMD_DATA, 0x0007, 0x0001}, // Display Control 1 (R007h) // Page 16 of SPFD5420A Datasheet - {LCD_STEP_SLEEP, 0, 50}, - {LCD_STEP_CMD_DATA, 0x0110, 0x0001}, // Power Control 6(R110h) // Page 30 of SPFD5420A Datasheet - {LCD_STEP_SLEEP, 0, 50}, - {LCD_STEP_CMD_DATA, 0x0100, 0x17B0}, // Power Control 1 (R100h) // Page 26 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0101, 0x0147}, // Power Control 2 (R101h) // Page 27 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0102, 0x019D}, // Power Control 3 (R102h) // Page 28 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0103, 0x3600}, // Power Control 4 (R103h) // Page 29 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0281, 0x0010}, // NVM read data 2 (R281h) // Page 34 of SPFD5420A Datasheet - {LCD_STEP_SLEEP, 0, 50}, - {LCD_STEP_CMD_DATA, 0x0102, 0x01BD}, // Power Control 3 (R102h) // Page 28 of SPFD5420A Datasheet - {LCD_STEP_SLEEP, 0, 50}, - - //--------------- Power control 1~6 ---------------// - {LCD_STEP_CMD_DATA, 0x0100, 0x16B0}, // Power Control 1 (R100h) // Page 26 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0101, 0x0147}, // Power Control 2 (R101h) // Page 27 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0102, 0x01BD}, // Power Control 3 (R102h) // Page 28 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0103, 0x2d00}, // Power Control 4 (R103h) // Page 29 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0107, 0x0000}, // Power Control 5 (R107h) // Page 30 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0110, 0x0001}, // Power Control 6(R110h) // Page 30 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0280, 0x0000}, // NVM read data 1 (R280h) // Page 33 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0281, 0x0006}, // NVM read data 2 (R281h) // Page 34 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0282, 0x0000}, // NVM read data 3 (R282h) // Page 34 of SPFD5420A Datasheet - - //------- Gamma 2.2 control (R300h to R30Fh) ------// - {LCD_STEP_CMD_DATA, 0x0300, 0x0101}, - {LCD_STEP_CMD_DATA, 0x0301, 0x0b27}, - {LCD_STEP_CMD_DATA, 0x0302, 0x132a}, - {LCD_STEP_CMD_DATA, 0x0303, 0x2a13}, - {LCD_STEP_CMD_DATA, 0x0304, 0x270b}, - {LCD_STEP_CMD_DATA, 0x0305, 0x0101}, - {LCD_STEP_CMD_DATA, 0x0306, 0x1205}, - {LCD_STEP_CMD_DATA, 0x0307, 0x0512}, - {LCD_STEP_CMD_DATA, 0x0308, 0x0005}, - {LCD_STEP_CMD_DATA, 0x0309, 0x0003}, - {LCD_STEP_CMD_DATA, 0x030A, 0x0f04}, - {LCD_STEP_CMD_DATA, 0x030B, 0x0f00}, - {LCD_STEP_CMD_DATA, 0x030C, 0x000f}, - {LCD_STEP_CMD_DATA, 0x030D, 0x040f}, - {LCD_STEP_CMD_DATA, 0x030E, 0x0300}, - {LCD_STEP_CMD_DATA, 0x030F, 0x0500}, - - {LCD_STEP_CMD_DATA, 0x0400, 0x3500}, // Base Image Number of Line (R400h) // Page 36 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0401, 0x0001}, // Base Image Display Control (R401h) // Page 39 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0404, 0x0000}, // Based Image Vertical Scroll Control (R404h) // Page 40 of SPFD5420A Datasheet - - //--------------- Normal set ---------------// - {LCD_STEP_CMD_DATA, 0x0000, 0x0000}, // ID Read Register (R000h) // Page 13 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0001, 0x0100}, // Driver Output Control Register (R001h) // Page 14 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0002, 0x0100}, // LCD Driving Waveform Control (R002h) // Page 14 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0003, 0x1030}, // Entry Mode (R003h) // Page 15 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0006, 0x0000}, // Display Control 1 (R007h) // Page 16 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0008, 0x0808}, // Display Control 2 (R008h) // Page 17 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0009, 0x0001}, // Display Control 3 (R009h) // Page 18 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x000B, 0x0010}, // Low Power Control (R00Bh) // Page 19 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x000C, 0x0000}, // External Display Interface Control 1 (R00Ch) // Page 19 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x000F, 0x0000}, // External Display Interface Control 2 (R00Fh) // Page 20 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0007, 0x0001}, // Display Control 1 (R007h) // Page 16 of SPFD5420A Datasheet - - //--------------- Panel interface control 1~6 ---------------// - {LCD_STEP_CMD_DATA, 0x0010, 0x0012}, // Panel Interface Control 1 (R010h) // Page 20 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0011, 0x0202}, // Panel Interface Control 2 (R011h) // Page 21 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0012, 0x0300}, // Panel Interface control 3 (R012h) // Page 22 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0020, 0x021E}, // Panel Interface control 4 (R020h) // Page 22 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0021, 0x0202}, // Panel Interface Control 5 (021Rh) // Page 24 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0022, 0x0100}, // Panel Interface Control 6 (R022h) // Page 25 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0090, 0x8000}, // Frame Marker Control (R090h) // Page 25 of SPFD5420A Datasheet - - //--------------- Partial display ---------------// - {LCD_STEP_CMD_DATA, 0x0210, 0x0000}, // Window Horizontal RAM Address Start (R210h) // Page 35 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0211, 0x00EF}, // Window Horziontal RAM Address End (R211h) // Page 35 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0212, 0x0000}, // Window Vertical RAM Address Start (R212h) // Page 35 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0213, 0x018F}, // Window Vertical RAM Address End (R213h) // Page 35 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0500, 0x0000}, // Display Position - Partial Display 1 (R500h) // Page 40 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0501, 0x0000}, // RAM Address Start - Partial Display 1 (R501h)// Page 40 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0502, 0x0000}, // RAM Address End - Partail Display 1 (R502h) // Page 40 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0503, 0x0000}, // Display Position - Partial Display 2 (R503h) // Page 40 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0504, 0x0000}, // RAM Address Start . Partial Display 2 (R504h)// Page 41 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0505, 0x0000}, // RAM Address End . Partial Display 2 (R505h) // Page 41 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0606, 0x0000}, // Pin Control (R606h) // Page 41 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x06F0, 0x0000}, // NVM Access Control (R6F0h) // Page 41 of SPFD5420A Datasheet - {LCD_STEP_CMD_DATA, 0x0007, 0x0173}, // Display Control 1 (R007h) // Page 16 of SPFD5420A Datasheet - {LCD_STEP_SLEEP, 0, 50}, - {LCD_STEP_CMD_DATA, 0x0007, 0x0171}, // Display Control 1 (R007h) // Page 16 of SPFD5420A Datasheet - {LCD_STEP_SLEEP, 0, 10}, - {LCD_STEP_CMD_DATA, 0x0007, 0x0173}, // Display Control 1 (R007h) // Page 16 of SPFD5420A Datasheet - {LCD_STEP_DONE, 0, 0}, -}; - -const struct ubicom32lcd_panel cfaf240400d = { - .desc = "CFAF240400D", - .init_seq = cfaf240400d_init, - .horz_reg = 0x0200, - .vert_reg = 0x0201, - .gram_reg = 0x0202, - .xres = 240, - .yres = 400, - .stride = 240, - .id = 0x5420, -}; -#endif - -#ifdef CONFIG_LCD_UBICOM32_CFAF240400F -static const struct ubicom32lcd_step cfaf320240f_init[] = { - {LCD_STEP_CMD_DATA, 0x0028, 0x0006}, // VCOM OTP Page 55-56 of SSD2119 datasheet - {LCD_STEP_CMD_DATA, 0x0000, 0x0001}, // start Oscillator Page 36 of SSD2119 datasheet - {LCD_STEP_CMD_DATA, 0x0010, 0x0000}, // Sleep mode Page 49 of SSD2119 datasheet - {LCD_STEP_CMD_DATA, 0x0001, 0x32EF}, // Driver Output Control Page 36-39 of SSD2119 datasheet - {LCD_STEP_CMD_DATA, 0x0002, 0x0600}, // LCD Driving Waveform Control Page 40-42 of SSD2119 datasheet - {LCD_STEP_CMD_DATA, 0x0003, 0x6A38}, // Power Control 1 Page 43-44 of SSD2119 datasheet - {LCD_STEP_CMD_DATA, 0x0011, 0x6870}, // Entry Mode Page 50-52 of SSD2119 datasheet - {LCD_STEP_CMD_DATA, 0X000F, 0x0000}, // Gate Scan Position Page 49 of SSD2119 datasheet - {LCD_STEP_CMD_DATA, 0X000B, 0x5308}, // Frame Cycle Control Page 45 of SSD2119 datasheet - {LCD_STEP_CMD_DATA, 0x000C, 0x0003}, // Power Control 2 Page 47 of SSD2119 datasheet - {LCD_STEP_CMD_DATA, 0x000D, 0x000A}, // Power Control 3 Page 48 of SSD2119 datasheet - {LCD_STEP_CMD_DATA, 0x000E, 0x2E00}, // Power Control 4 Page 48 of SSD2119 datasheet - {LCD_STEP_CMD_DATA, 0x001E, 0x00BE}, // Power Control 5 Page 53 of SSD2119 datasheet - {LCD_STEP_CMD_DATA, 0x0025, 0x8000}, // Frame Frequency Control Page 53 of SSD2119 datasheet - {LCD_STEP_CMD_DATA, 0x0026, 0x7800}, // Analog setting Page 54 of SSD2119 datasheet - {LCD_STEP_CMD_DATA, 0x004E, 0x0000}, // Ram Address Set Page 58 of SSD2119 datasheet - {LCD_STEP_CMD_DATA, 0x004F, 0x0000}, // Ram Address Set Page 58 of SSD2119 datasheet - {LCD_STEP_CMD_DATA, 0x0012, 0x08D9}, // Sleep mode Page 49 of SSD2119 datasheet - - // Gamma Control (R30h to R3Bh) -- Page 56 of SSD2119 datasheet - {LCD_STEP_CMD_DATA, 0x0030, 0x0000}, - {LCD_STEP_CMD_DATA, 0x0031, 0x0104}, - {LCD_STEP_CMD_DATA, 0x0032, 0x0100}, - {LCD_STEP_CMD_DATA, 0x0033, 0x0305}, - {LCD_STEP_CMD_DATA, 0x0034, 0x0505}, - {LCD_STEP_CMD_DATA, 0x0035, 0x0305}, - {LCD_STEP_CMD_DATA, 0x0036, 0x0707}, - {LCD_STEP_CMD_DATA, 0x0037, 0x0300}, - {LCD_STEP_CMD_DATA, 0x003A, 0x1200}, - {LCD_STEP_CMD_DATA, 0x003B, 0x0800}, - - {LCD_STEP_CMD_DATA, 0x0007, 0x0033}, // Display Control Page 45 of SSD2119 datasheet - - {LCD_STEP_CMD_DATA, 0x0044, 0xEF00}, // Vertical RAM address position Page 57 of SSD2119 datasheet - {LCD_STEP_CMD_DATA, 0x0045, 0x0000}, // Horizontal RAM address position Page 57 of SSD2119 datasheet - {LCD_STEP_CMD_DATA, 0x0046, 0x013F}, // Horizontal RAM address position Page 57 of SSD2119 datasheet - - {LCD_STEP_SLEEP, 0, 150}, - - {LCD_STEP_DONE, 0, 0}, -}; - -const struct ubicom32lcd_panel cfaf320240f = { - .desc = "CFAF320240F", - .init_seq = cfaf320240f_init, - .horz_reg = 0x4e, - .vert_reg = 0x4f, - .gram_reg = 0x22, - .xres = 320, - .yres = 240, - .stride = 320, - .id = 0x9919, -}; -#endif - -const struct ubicom32lcd_panel *ubicom32lcd_panels[] = { -#ifdef CONFIG_LCD_UBICOM32_CFAF240400KTTS_180 - &cfaf240320ktts_180, -#endif -#ifdef CONFIG_LCD_UBICOM32_CFAF240400KTTS - &cfaf240320ktts_0, -#endif -#ifdef CONFIG_LCD_UBICOM32_CFAF240400D - &cfaf240400d, -#endif -#ifdef CONFIG_LCD_UBICOM32_TFT2N0369E_P - &tft2n0369ep, -#endif -#ifdef CONFIG_LCD_UBICOM32_TFT2N0369E_L - &tft2n0369e, -#endif -#ifdef CONFIG_LCD_UBICOM32_CFAF240400F - &cfaf320240f, -#endif - NULL, -}; - -#endif diff --git a/target/linux/ubicom32/files/drivers/video/backlight/ubicom32lcdpower.c b/target/linux/ubicom32/files/drivers/video/backlight/ubicom32lcdpower.c deleted file mode 100644 index 6aeed43bc8..0000000000 --- a/target/linux/ubicom32/files/drivers/video/backlight/ubicom32lcdpower.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * drivers/video/backlight/ubicom32lcdpowerpower.c - * LCD power driver for the Ubicom32 platform - * - * (C) Copyright 2009, Ubicom, Inc. - * - * This file is part of the Ubicom32 Linux Kernel Port. - * - * The Ubicom32 Linux Kernel Port is free software: you can redistribute - * it and/or modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version 2 of the - * License, or (at your option) any later version. - * - * The Ubicom32 Linux Kernel Port is distributed in the hope that it - * will be useful, but WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - * the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the Ubicom32 Linux Kernel Port. If not, - * see <http://www.gnu.org/licenses/>. - * - * Ubicom32 implementation derived from (with many thanks): - * arch/m68knommu - * arch/blackfin - * arch/parisc - */ -#include <linux/init.h> -#include <linux/kernel.h> -#include <linux/module.h> -#include <linux/platform_device.h> -#include <linux/lcd.h> -#include <linux/fb.h> -#include <linux/gpio.h> - -#include <asm/ubicom32lcdpower.h> -#include <asm/ip5000.h> - -#define DRIVER_NAME "ubicom32lcdpower" - -struct ubicom32lcdpower_data { - /* - * Pointer to the platform data structure. Keep this around since we need values - * from it to set the backlight intensity. - */ - const struct ubicom32lcdpower_platform_data *pdata; - - /* - * LCD device, we have to save this for use when we remove ourselves. - */ - struct lcd_device *lcddev; -}; - -/* - * ubicom32lcdpower_set_power - */ -static int ubicom32lcdpower_set_power(struct lcd_device *ld, int power) -{ - struct ubicom32lcdpower_data *ud = (struct ubicom32lcdpower_data *)lcd_get_data(ld); - if (power == FB_BLANK_UNBLANK) { - gpio_direction_output(ud->pdata->vgh_gpio, ud->pdata->vgh_polarity); - return 0; - } - - gpio_direction_output(ud->pdata->vgh_gpio, !ud->pdata->vgh_polarity); - return 0; -} - -/* - * ubicom32lcdpower_get_power - */ -static int ubicom32lcdpower_get_power(struct lcd_device *ld) -{ - struct ubicom32lcdpower_data *ud = (struct ubicom32lcdpower_data *)lcd_get_data(ld); - int vgh = gpio_get_value(ud->pdata->vgh_gpio); - if ((vgh && ud->pdata->vgh_polarity) || (!vgh && !ud->pdata->vgh_polarity)) { - return 1; - } - - return 0; -} - -static struct lcd_ops ubicom32lcdpower_ops = { - .get_power = ubicom32lcdpower_get_power, - .set_power = ubicom32lcdpower_set_power, -}; - -/* - * ubicom32lcdpower_probe - */ -static int ubicom32lcdpower_probe(struct platform_device *pdev) -{ - const struct ubicom32lcdpower_platform_data *pdata = pdev->dev.platform_data; - struct ubicom32lcdpower_data *ud; - struct lcd_device *lcddev; - int retval; - - /* - * Check to see if we have any platform data, if we don't have a LCD to control - */ - if (!pdata) { - return -ENODEV; - } - - /* - * Allocate our private data - */ - ud = kzalloc(sizeof(struct ubicom32lcdpower_data), GFP_KERNEL); - if (!ud) { - return -ENOMEM; - } - - ud->pdata = pdata; - - /* - * Request our GPIOs - */ - retval = gpio_request(pdata->vgh_gpio, "vgh"); - if (retval) { - dev_err(&pdev->dev, "Failed to allocate vgh GPIO\n"); - goto fail_gpio; - } - - /* - * Register our lcd device - */ - lcddev = lcd_device_register(DRIVER_NAME, &pdev->dev, ud, &ubicom32lcdpower_ops); - if (IS_ERR(lcddev)) { - retval = PTR_ERR(lcddev); - goto fail; - } - - ud->lcddev = lcddev; - platform_set_drvdata(pdev, ud); - - ubicom32lcdpower_set_power(lcddev, FB_BLANK_UNBLANK); - - printk(KERN_INFO DRIVER_NAME ": LCD driver started\n"); - - return 0; - -fail: - gpio_free(pdata->vgh_gpio); - -fail_gpio: - platform_set_drvdata(pdev, NULL); - kfree(ud); - return retval; -} - -/* - * ubicom32lcdpower_remove - */ -static int __exit ubicom32lcdpower_remove(struct platform_device *pdev) -{ - struct ubicom32lcdpower_data *ud = platform_get_drvdata(pdev); - - lcd_device_unregister(ud->lcddev); - platform_set_drvdata(pdev, NULL); - kfree(ud); - - return 0; -} - -static struct platform_driver ubicom32lcdpower_driver = { - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE, - }, - - .remove = __exit_p(ubicom32lcdpower_remove), -}; - -/* - * ubicom32lcdpower_init - */ -static int __init ubicom32lcdpower_init(void) -{ - return platform_driver_probe(&ubicom32lcdpower_driver, ubicom32lcdpower_probe); -} -module_init(ubicom32lcdpower_init); - -/* - * ubicom32lcdpower_exit - */ -static void __exit ubicom32lcdpower_exit(void) -{ - platform_driver_unregister(&ubicom32lcdpower_driver); -} -module_exit(ubicom32lcdpower_exit); - -MODULE_AUTHOR("Patrick Tjin <@ubicom.com>"); -MODULE_DESCRIPTION("Ubicom32 lcd power driver"); -MODULE_LICENSE("GPL"); diff --git a/target/linux/ubicom32/files/drivers/video/ubicom32fb.c b/target/linux/ubicom32/files/drivers/video/ubicom32fb.c deleted file mode 100644 index 4193560f7c..0000000000 --- a/target/linux/ubicom32/files/drivers/video/ubicom32fb.c +++ /dev/null @@ -1,779 +0,0 @@ -/* - * drivers/video/ubicom32fb.c - * Ubicom32 frame buffer driver - * - * (C) Copyright 2009, Ubicom, Inc. - * - * This file is part of the Ubicom32 Linux Kernel Port. - * - * The Ubicom32 Linux Kernel Port is free software: you can redistribute - * it and/or modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version 2 of the - * License, or (at your option) any later version. - * - * The Ubicom32 Linux Kernel Port is distributed in the hope that it - * will be useful, but WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - * the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the Ubicom32 Linux Kernel Port. If not, - * see <http://www.gnu.org/licenses/>. - * - * Ubicom32 implementation derived from (with many thanks): - * arch/m68knommu - * arch/blackfin - * arch/parisc - */ - -/* - * This driver was based on skeletonfb.c, Skeleton for a frame buffer device by - * Geert Uytterhoeven. - */ - -#include <linux/device.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/version.h> -#include <linux/errno.h> -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/fb.h> -#include <linux/init.h> -#include <linux/dma-mapping.h> -#include <linux/platform_device.h> -#include <linux/device.h> -#include <linux/uaccess.h> -#include <linux/interrupt.h> - -#include <asm/io.h> -#include <asm/ip5000.h> -#include <asm/vdc_tio.h> -#include <asm/ubicom32fb.h> - -#define DRIVER_NAME "ubicom32fb" -#define DRIVER_DESCRIPTION "Ubicom32 frame buffer driver" - -#define PALETTE_ENTRIES_NO 16 - -/* - * Option variables - * - * vram_size: VRAM size in kilobytes, subject to alignment - */ -static int vram_size = 0; -module_param(vram_size, int, 0); -MODULE_PARM_DESC(vram, "VRAM size, in kilobytes to allocate, should be at least the size of one screen, subject to alignment"); -static int init_value = 0; -module_param(init_value, int, 0); -MODULE_PARM_DESC(init, "Initial value of the framebuffer (16-bit number)."); - -/* - * fb_fix_screeninfo defines the non-changeable properties of the VDC, depending on what mode it is in. - */ -static struct fb_fix_screeninfo ubicom32fb_fix = { - .id = "Ubicom32", - .type = FB_TYPE_PACKED_PIXELS, - .visual = FB_VISUAL_TRUECOLOR, - .accel = FB_ACCEL_UBICOM32, -}; - -/* - * Filled in at probe time when we find out what the hardware supports - */ -static struct fb_var_screeninfo ubicom32fb_var; - -/* - * Private data structure - */ -struct ubicom32fb_drvdata { - struct fb_info *fbinfo; - bool cmap_alloc; - - /* - * The address of the framebuffer in memory - */ - void *fb; - void *fb_aligned; - - /* - * Total size of vram including alignment allowance - */ - u32 total_vram_size; - - /* - * Interrupt to set when changing registers - */ - u32 vp_int; - - /* - * Optional: Interrupt used by TIO to signal us - */ - u32 rx_int; - - /* - * Base address of the regs for VDC_TIO - */ - volatile struct vdc_tio_vp_regs *regs; - - /* - * non-zero if we are in yuv mode - */ - u8_t is_yuv; - - /* - * Fake palette of 16 colors - */ - u32 pseudo_palette[PALETTE_ENTRIES_NO]; - - /* - * Wait queue and lock used to block when we need to wait - * for something to happen. - */ - wait_queue_head_t waitq; - struct mutex lock; - -}; - -/* - * ubicom32fb_set_next_frame - * Sets the next frame buffer to display - * - * if sync is TRUE then this function will block until the hardware - * acknowledges the change - */ -static inline void ubicom32fb_set_next_frame(struct ubicom32fb_drvdata *ud, void *fb, u8_t sync) -{ - ud->regs->next_frame_flags = ud->is_yuv ? VDCTIO_NEXT_FRAME_FLAG_YUV : 0; - ud->regs->next_frame = (void *)((u32_t)fb | 1); - - /* - * If we have interrupts, then we can wait on it - */ - if (ud->rx_int != -1) { - DEFINE_WAIT(wait); - unsigned long flags; - - spin_lock_irqsave(&ud->lock, flags); - prepare_to_wait(&ud->waitq, &wait, TASK_INTERRUPTIBLE); - spin_unlock_irqrestore(&ud->lock, flags); - schedule(); - finish_wait(&ud->waitq, &wait); - return; - } - - /* - * No interrupt, we will just spin here - */ - while (sync && ((u32_t)ud->regs->next_frame & 1)); -} - -/* - * ubicom32fb_send_command - * Sends a command/data pair to the VDC - */ -static inline void ubicom32fb_send_command(struct ubicom32fb_drvdata *ud, u16 command, u8_t block) -{ - ud->regs->command = command; - ubicom32_set_interrupt(ud->vp_int); - while (block && ud->regs->command); -} - -/* - * ubicom32fb_ioctl - * Handles any ioctls sent to us - */ -static int ubicom32fb_ioctl(struct fb_info *fbi, unsigned int cmd, - unsigned long arg) -{ - struct ubicom32fb_drvdata *ud = (struct ubicom32fb_drvdata *)fbi->par; - void __user *argp = (void __user *)arg; - int retval = -EFAULT; - - switch (cmd) { - case UBICOM32FB_IOCTL_SET_NEXT_FRAME_SYNC: - // check alignment, return -EINVAL if necessary - ubicom32fb_set_next_frame(ud, argp, 1); - retval = 0; - break; - - case UBICOM32FB_IOCTL_SET_NEXT_FRAME: - // check alignment, return -EINVAL if necessary - ubicom32fb_set_next_frame(ud, argp, 0); - retval = 0; - break; - - case UBICOM32FB_IOCTL_SET_MODE: - if (!(ud->regs->caps & VDCTIO_CAPS_SUPPORTS_SCALING)) { - break; - } else { - struct ubicom32fb_mode mode; - volatile struct vdc_tio_vp_regs *regs = ud->regs; - u32_t flags = 0; - - if (copy_from_user(&mode, argp, sizeof(mode))) { - break; - } - - regs->x_in = mode.width; - regs->y_in = mode.height; - regs->x_out = regs->xres; - regs->y_out = regs->yres; - if (mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_YUV_SCAN_ORDER) { - flags |= VDCTIO_SCALE_FLAG_YUV_SCAN_ORDER; - } - if (mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_YUV_BLOCK_ORDER) { - flags |= VDCTIO_SCALE_FLAG_YUV_BLOCK_ORDER; - } - ud->is_yuv = mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_YUV; - if (ud->is_yuv) { - flags |= VDCTIO_SCALE_FLAG_YUV; - } - if (mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_VRANGE_16_255) { - flags |= VDCTIO_SCALE_FLAG_VRANGE_16_255; - } - if (mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_VRANGE_0_255) { - flags |= VDCTIO_SCALE_FLAG_VRANGE_0_255; - } - if (mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_VSUB) { - flags |= VDCTIO_SCALE_FLAG_VSUB; - } - if (mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_HSUB_2_1) { - flags |= VDCTIO_SCALE_FLAG_HSUB_2_1; - } - if (mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_HSUB_1_1) { - flags |= VDCTIO_SCALE_FLAG_HSUB_1_1; - } - if (mode.flags & UBICOM32FB_IOCTL_SET_MODE_FLAG_SCALE_ENABLE) { - flags |= VDCTIO_SCALE_FLAG_ENABLE; - } - if (mode.next_frame) { - flags |= VDCTIO_SCALE_FLAG_SET_FRAME_BUFFER; - regs->next_frame = mode.next_frame; - } - - regs->scale_flags = flags; - ubicom32fb_send_command(ud, VDCTIO_COMMAND_SET_SCALE_MODE, 1); - retval = 0; - break; - } - - default: - retval = -ENOIOCTLCMD; - break; - } - - return retval; -} - -/* - * ubicom32fb_interrupt - * Called by the OS when the TIO has set the rx_int - */ -static irqreturn_t ubicom32fb_interrupt(int vec, void *appdata) -{ - struct ubicom32fb_drvdata *ud = (struct ubicom32fb_drvdata *)appdata; - - spin_lock(&ud->lock); - if (waitqueue_active(&ud->waitq)) { - wake_up(&ud->waitq); - } - spin_unlock(&ud->lock); - - return IRQ_HANDLED; -} - -/* - * ubicom32fb_pan_display - * Pans the display to a given location. Supports only y direction panning. - */ -static int ubicom32fb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fbi) -{ - struct ubicom32fb_drvdata *ud = (struct ubicom32fb_drvdata *)fbi->par; - void *new_addr; - - /* - * Get the last y line that would be displayed. Since we don't support YWRAP, - * it must be less than our virtual y size. - */ - u32 lasty = var->yoffset + var->yres; - if (lasty > fbi->var.yres_virtual) { - /* - * We would fall off the end of our frame buffer if we panned here. - */ - return -EINVAL; - } - - if (var->xoffset) { - /* - * We don't support panning in the x direction - */ - return -EINVAL; - } - - /* - * Everything looks sane, go ahead and pan - * - * We have to calculate a new address for the VDC to look at - */ - new_addr = ud->fb_aligned + (var->yoffset * fbi->fix.line_length); - - /* - * Send down the command. The buffer will switch at the next vertical blank - */ - ubicom32fb_set_next_frame(ud, (void *)new_addr, 0); - - return 0; -} - -/* - * ubicom32fb_setcolreg - * Sets a color in our virtual palette - */ -static int ubicom32fb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *fbi) -{ - u32 *palette = fbi->pseudo_palette; - - if (regno >= PALETTE_ENTRIES_NO) { - return -EINVAL; - } - - /* - * We only use 8 bits from each color - */ - red >>= 8; - green >>= 8; - blue >>= 8; - - /* - * Convert any grayscale values - */ - if (fbi->var.grayscale) { - u16 gray = red + green + blue; - gray += (gray >> 2) + (gray >> 3) - (gray >> 7); - gray >>= 2; - if (gray > 255) { - gray = 255; - } - red = gray; - blue = gray; - green = gray; - } - - palette[regno] = (red << fbi->var.red.offset) | (green << fbi->var.green.offset) | - (blue << fbi->var.blue.offset); - - return 0; -} - -/* - * ubicom32fb_mmap - */ -static int ubicom32fb_mmap(struct fb_info *info, struct vm_area_struct *vma) -{ - struct ubicom32fb_drvdata *drvdata = (struct ubicom32fb_drvdata *)info->par; - - vma->vm_start = (unsigned long)(drvdata->fb_aligned); - - vma->vm_end = vma->vm_start + info->fix.smem_len; - - /* For those who don't understand how mmap works, go read - * Documentation/nommu-mmap.txt. - * For those that do, you will know that the VM_MAYSHARE flag - * must be set in the vma->vm_flags structure on noMMU - * Other flags can be set, and are documented in - * include/linux/mm.h - */ - - vma->vm_flags |= VM_MAYSHARE | VM_SHARED; - - return 0; -} - -/* - * ubicom32fb_blank - */ -static int ubicom32fb_blank(int blank_mode, struct fb_info *fbi) -{ - return 0; -#if 0 - struct ubicom32fb_drvdata *drvdata = to_ubicom32fb_drvdata(fbi); - - switch (blank_mode) { - case FB_BLANK_UNBLANK: - /* turn on panel */ - ubicom32fb_out_be32(drvdata, REG_CTRL, drvdata->reg_ctrl_default); - break; - - case FB_BLANK_NORMAL: - case FB_BLANK_VSYNC_SUSPEND: - case FB_BLANK_HSYNC_SUSPEND: - case FB_BLANK_POWERDOWN: - /* turn off panel */ - ubicom32fb_out_be32(drvdata, REG_CTRL, 0); - default: - break; - - } - return 0; /* success */ -#endif -} - -static struct fb_ops ubicom32fb_ops = -{ - .owner = THIS_MODULE, - .fb_pan_display = ubicom32fb_pan_display, - .fb_setcolreg = ubicom32fb_setcolreg, - .fb_blank = ubicom32fb_blank, - .fb_mmap = ubicom32fb_mmap, - .fb_ioctl = ubicom32fb_ioctl, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, -}; - -/* - * ubicom32fb_release - */ -static int ubicom32fb_release(struct device *dev) -{ - struct ubicom32fb_drvdata *ud = dev_get_drvdata(dev); - -#if !defined(CONFIG_FRAMEBUFFER_CONSOLE) && defined(CONFIG_LOGO) - //ubicom32fb_blank(VESA_POWERDOWN, &drvdata->info); -#endif - - unregister_framebuffer(ud->fbinfo); - - if (ud->cmap_alloc) { - fb_dealloc_cmap(&ud->fbinfo->cmap); - } - - if (ud->fb) { - kfree(ud->fb); - } - - if (ud->rx_int != -1) { - free_irq(ud->rx_int, ud); - } - - /* - * Turn off the display - */ - //ubicom32fb_out_be32(drvdata, REG_CTRL, 0); - //iounmap(drvdata->regs); - - framebuffer_release(ud->fbinfo); - dev_set_drvdata(dev, NULL); - - return 0; -} - -/* - * ubicom32fb_platform_probe - */ -static int __init ubicom32fb_platform_probe(struct platform_device *pdev) -{ - struct ubicom32fb_drvdata *ud; - struct resource *irq_resource_rx; - struct resource *irq_resource_tx; - struct resource *mem_resource; - struct fb_info *fbinfo; - int rc; - size_t fbsize; - struct device *dev = &pdev->dev; - int offset; - struct vdc_tio_vp_regs *regs; - - /* - * Get our resources - */ - irq_resource_tx = platform_get_resource(pdev, IORESOURCE_IRQ, 0); - if (!irq_resource_tx) { - dev_err(dev, "No tx IRQ resource assigned\n"); - return -ENODEV; - } - - irq_resource_rx = platform_get_resource(pdev, IORESOURCE_IRQ, 1); - if (!irq_resource_rx) { - dev_err(dev, "No rx IRQ resource assigned\n"); - return -ENODEV; - } - - mem_resource = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!mem_resource || !mem_resource->start) { - dev_err(dev, "No mem resource assigned\n"); - return -ENODEV; - } - regs = (struct vdc_tio_vp_regs *)mem_resource->start; - if (regs->version != VDCTIO_VP_VERSION) { - dev_err(dev, "VDCTIO is not compatible with this driver tio:%x drv:%x\n", - regs->version, VDCTIO_VP_VERSION); - return -ENODEV; - } - - /* - * This is the minimum VRAM size - */ - fbsize = regs->xres * regs->yres * (regs->bpp / 8); - if (!vram_size) { - vram_size = (fbsize + 1023) / 1024; - } else { - if (fbsize > (vram_size * 1024)) { - dev_err(dev, "Not enough VRAM for display, need >= %u bytes\n", fbsize); - return -ENOMEM; // should be ebadparam? - } - } - - /* - * Allocate the framebuffer instance + our private data - */ - fbinfo = framebuffer_alloc(sizeof(struct ubicom32fb_drvdata), &pdev->dev); - if (!fbinfo) { - dev_err(dev, "Not enough memory to allocate instance.\n"); - return -ENOMEM; - } - - /* - * Fill in our private data. - */ - ud = (struct ubicom32fb_drvdata *)fbinfo->par; - ud->fbinfo = fbinfo; - ud->regs = (struct vdc_tio_vp_regs *)(mem_resource->start); - dev_set_drvdata(dev, ud); - - ud->vp_int = irq_resource_tx->start; - - /* - * If we were provided an rx_irq then we need to init the appropriate - * queues, locks, and functions. - */ - ud->rx_int = -1; - if (irq_resource_rx->start != DEVTREE_IRQ_NONE) { - init_waitqueue_head(&ud->waitq); - mutex_init(&ud->lock); - if (request_irq(ud->rx_int, ubicom32fb_interrupt, IRQF_SHARED, "ubicom32fb_rx", ud)) { - dev_err(dev, "Couldn't request rx IRQ\n"); - rc = -ENOMEM; - goto fail; - } - ud->rx_int = irq_resource_rx->start; - } - - /* - * Allocate and align the requested amount of VRAM - */ - ud->total_vram_size = (vram_size * 1024) + regs->fb_align; - ud->fb = kmalloc(ud->total_vram_size, GFP_KERNEL); - if (ud->fb == NULL) { - dev_err(dev, "Couldn't allocate VRAM\n"); - rc = -ENOMEM; - goto fail; - } - - offset = (u32_t)ud->fb & (regs->fb_align - 1); - if (!offset) { - ud->fb_aligned = ud->fb; - } else { - offset = regs->fb_align - offset; - ud->fb_aligned = ud->fb + offset; - } - - /* - * Clear the entire frame buffer - */ - if (!init_value) { - memset(ud->fb_aligned, 0, vram_size * 1024); - } else { - unsigned short *p = ud->fb_aligned; - int i; - for (i = 0; i < ((vram_size * 1024) / sizeof(u16_t)); i++) { - *p++ = init_value; - } - } - - /* - * Fill in the fb_var_screeninfo structure - */ - memset(&ubicom32fb_var, 0, sizeof(ubicom32fb_var)); - ubicom32fb_var.bits_per_pixel = regs->bpp; - ubicom32fb_var.red.offset = regs->rshift; - ubicom32fb_var.green.offset = regs->gshift; - ubicom32fb_var.blue.offset = regs->bshift; - ubicom32fb_var.red.length = regs->rbits; - ubicom32fb_var.green.length = regs->gbits; - ubicom32fb_var.blue.length = regs->bbits; - ubicom32fb_var.activate = FB_ACTIVATE_NOW; - -#if 0 - /* - * Turn on the display - */ - ud->reg_ctrl_default = REG_CTRL_ENABLE; - if (regs->rotate_screen) - ud->reg_ctrl_default |= REG_CTRL_ROTATE; - ubicom32fb_out_be32(ud, REG_CTRL, ud->reg_ctrl_default); -#endif - - /* - * Fill in the fb_info structure - */ - ud->fbinfo->device = dev; - ud->fbinfo->screen_base = (void *)ud->fb_aligned; - ud->fbinfo->fbops = &ubicom32fb_ops; - ud->fbinfo->fix = ubicom32fb_fix; - ud->fbinfo->fix.smem_start = (u32)ud->fb_aligned; - ud->fbinfo->fix.smem_len = vram_size * 1024; - ud->fbinfo->fix.line_length = regs->xres * (regs->bpp / 8); - ud->fbinfo->fix.mmio_start = (u32)regs; - ud->fbinfo->fix.mmio_len = sizeof(struct vdc_tio_vp_regs); - - /* - * We support panning in the y direction only - */ - ud->fbinfo->fix.xpanstep = 0; - ud->fbinfo->fix.ypanstep = 1; - - ud->fbinfo->pseudo_palette = ud->pseudo_palette; - ud->fbinfo->flags = FBINFO_DEFAULT; - ud->fbinfo->var = ubicom32fb_var; - ud->fbinfo->var.xres = regs->xres; - ud->fbinfo->var.yres = regs->yres; - - /* - * We cannot pan in the X direction, so xres_virtual is regs->xres - * We can pan in the Y direction, so yres_virtual is vram_size / ud->fbinfo->fix.line_length - */ - ud->fbinfo->var.xres_virtual = regs->xres; - ud->fbinfo->var.yres_virtual = (vram_size * 1024) / ud->fbinfo->fix.line_length; - - //ud->fbinfo->var.height = regs->height_mm; - //ud->fbinfo->var.width = regs->width_mm; - - /* - * Allocate a color map - */ - rc = fb_alloc_cmap(&ud->fbinfo->cmap, PALETTE_ENTRIES_NO, 0); - if (rc) { - dev_err(dev, "Fail to allocate colormap (%d entries)\n", - PALETTE_ENTRIES_NO); - goto fail; - } - ud->cmap_alloc = true; - - /* - * Register new frame buffer - */ - rc = register_framebuffer(ud->fbinfo); - if (rc) { - dev_err(dev, "Could not register frame buffer\n"); - goto fail; - } - - /* - * Start up the VDC - */ - ud->regs->next_frame = ud->fb; - ubicom32fb_send_command(ud, VDCTIO_COMMAND_START, 0); - - /* - * Tell the log we are here - */ - dev_info(dev, "fbaddr=%p align=%p, size=%uKB screen(%ux%u) virt(%ux%u), regs=%p irqtx=%u irqrx=%u\n", - ud->fb, ud->fb_aligned, vram_size, ud->fbinfo->var.xres, ud->fbinfo->var.yres, - ud->fbinfo->var.xres_virtual, ud->fbinfo->var.yres_virtual, ud->regs, - irq_resource_tx->start, irq_resource_rx->start); - - /* - * Success - */ - return 0; - -fail: - ubicom32fb_release(dev); - return rc; -} - -/* - * ubicom32fb_platform_remove - */ -static int ubicom32fb_platform_remove(struct platform_device *pdev) -{ - dev_info(&(pdev->dev), "Ubicom32 FB Driver Remove\n"); - return ubicom32fb_release(&pdev->dev); -} - -static struct platform_driver ubicom32fb_platform_driver = { - .probe = ubicom32fb_platform_probe, - .remove = ubicom32fb_platform_remove, - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE, - }, -}; - -#ifndef MODULE -/* - * ubicom32fb_setup - * Process kernel boot options - */ -static int __init ubicom32fb_setup(char *options) -{ - char *this_opt; - - if (!options || !*options) { - return 0; - } - - while ((this_opt = strsep(&options, ",")) != NULL) { - if (!*this_opt) { - continue; - } - - if (!strncmp(this_opt, "init_value=", 10)) { - init_value = simple_strtoul(this_opt + 11, NULL, 0); - continue; - } - - if (!strncmp(this_opt, "vram_size=", 10)) { - vram_size = simple_strtoul(this_opt + 10, NULL, 0); - continue; - } - } - return 0; -} -#endif /* MODULE */ - -/* - * ubicom32fb_init - */ -static int __devinit ubicom32fb_init(void) -{ -#ifndef MODULE - /* - * Get kernel boot options (in 'video=ubicom32fb:<options>') - */ - char *option = NULL; - - if (fb_get_options(DRIVER_NAME, &option)) { - return -ENODEV; - } - ubicom32fb_setup(option); -#endif /* MODULE */ - - return platform_driver_register(&ubicom32fb_platform_driver); -} -module_init(ubicom32fb_init); - -/* - * ubicom32fb_exit - */ -static void __exit ubicom32fb_exit(void) -{ - platform_driver_unregister(&ubicom32fb_platform_driver); -} -module_exit(ubicom32fb_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Patrick Tjin <@ubicom.com>"); -MODULE_DESCRIPTION(DRIVER_DESCRIPTION); diff --git a/target/linux/ubicom32/files/drivers/video/ubicom32plio80.c b/target/linux/ubicom32/files/drivers/video/ubicom32plio80.c deleted file mode 100644 index 2e13fd7075..0000000000 --- a/target/linux/ubicom32/files/drivers/video/ubicom32plio80.c +++ /dev/null @@ -1,780 +0,0 @@ -/* - * drivers/video/ubicom32plio80.c - * Ubicom32 80 bus PLIO buffer driver - * - * (C) Copyright 2009, Ubicom, Inc. - * - * This file is part of the Ubicom32 Linux Kernel Port. - * - * The Ubicom32 Linux Kernel Port is free software: you can redistribute - * it and/or modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version 2 of the - * License, or (at your option) any later version. - * - * The Ubicom32 Linux Kernel Port is distributed in the hope that it - * will be useful, but WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - * the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the Ubicom32 Linux Kernel Port. If not, - * see <http://www.gnu.org/licenses/>. - */ - -/* - * This driver was based on skeletonfb.c, Skeleton for a frame buffer device by - * Geert Uytterhoeven. - */ - -#include <linux/device.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/version.h> -#include <linux/errno.h> -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/fb.h> -#include <linux/init.h> -#include <linux/interrupt.h> -#include <linux/dma-mapping.h> -#include <linux/platform_device.h> -#include <linux/device.h> -#include <linux/uaccess.h> -#include <asm/plio.h> - -#define DRIVER_NAME "ubicom32plio80" -#define DRIVER_DESCRIPTION "Ubicom32 80 bus PLIO frame buffer driver" - -#define PALETTE_ENTRIES_NO 16 - -/* - * Option variables - * - * vram_size: VRAM size in kilobytes, subject to alignment - */ -static int vram_size = 0; -module_param(vram_size, int, 0); -MODULE_PARM_DESC(vram_size, "VRAM size, in kilobytes to allocate, should be at least the size of one screen, subject to alignment"); - -static int xres = 240; -module_param(xres, int, 0); -MODULE_PARM_DESC(xres, "x (horizontal) resolution"); - -static int yres = 320; -module_param(yres, int, 0); -MODULE_PARM_DESC(yres, "y (vertical) resolution"); - -static int bgr = 0; -module_param(bgr, int, 0); -MODULE_PARM_DESC(bgr, "display is BGR (Blue is MSB)"); - -#define BITS_PER_PIXEL 16 - -/* - * Buffer alignment, must not be 0 - */ -#define UBICOM32PLIO80_ALIGNMENT 4 - -/* - * PLIO FSM - * 16-bit data bus on port I - * CS on EXTCTL[6] - * WR on EXTCTL[4] - */ -static const plio_fctl_t plio_fctl = { - .fctl0 = { - .ptif_port_mode = PLIO_PORT_MODE_DI, - .ptif_portd_cfg = 0, - .ptif_porti_cfg = 3, - .edif_ds = 6, - .edif_cmp_mode = 1, - .ecif_extclk_ena = 0, // enable clock output on PD7 table 2.65/p111 says extctl[0]? - .icif_clk_src_sel = PLIO_CLK_IO, - }, - .fctl2 = { - .icif_eclk_div = 10, - .icif_iclk_div = 10, - }, - - }; - - static const plio_config_t plio_config = { - .pfsm = { - /* - * Table 12.63 - */ - .grpsel[0] = {1,1,1,1,1,1,1,1,1,1}, - - /* - * Table 12.66 Counter load value - */ - .cs_lut[0] = {0,0,0,0,0,0,0,0}, - - /* - * Table 2.75 PLIO PFSM Configuration Registers - */ - // 3 2 1 0 - .extctl_o_lut[0] = {0x3f, 0x2f, 0x3f, 0x3f}, - // 7 6 5 4 - .extctl_o_lut[1] = {0x3f, 0x3f, 0x3f, 0x2f}, - }, - .edif = { - .odr_oe = 0xffff, - }, - .ecif = { - .output_ena = (1 << 6) | (1 << 4), - }, -}; - -static const u32_t ubicom32plio80_plio_fsm[] = { - // 0-F - 0x00070007, 0x00070007, - 0x00070007, 0x00070007, - 0x00070007, 0x00070007, - 0x00070007, 0x00070007, - - 0x16260806, 0x16260806, - 0x16260806, 0x16260806, - 0x16260806, 0x16260806, - 0x16260806, 0x16260806, - - // 10 - 1f - 0x22061806, 0x22061806, - 0x22061806, 0x22061806, - 0x22061806, 0x22061806, - 0x22061806, 0x22061806, - - 0x22061806, 0x22061806, - 0x22061806, 0x22061806, - 0x22061806, 0x22061806, - 0x22061806, 0x22061806, - - // 20 - 2f - 0x00070806, 0x00070806, - 0x00070806, 0x00070806, - 0x00070806, 0x00070806, - 0x00070806, 0x00070806, - - 0x00070806, 0x00070806, - 0x00070806, 0x00070806, - 0x00070806, 0x00070806, - 0x00070806, 0x00070806, -}; - -/* - * fb_fix_screeninfo defines the non-changeable properties of the VDC, depending on what mode it is in. - */ -static struct fb_fix_screeninfo ubicom32plio80_fix = { - .id = "Ubicom32", - .type = FB_TYPE_PACKED_PIXELS, - .visual = FB_VISUAL_TRUECOLOR, - .accel = FB_ACCEL_UBICOM32_PLIO80, -}; - -/* - * Filled in at probe time when we find out what the hardware supports - */ -static struct fb_var_screeninfo ubicom32plio80_var; - -/* - * Private data structure - */ -struct ubicom32plio80_drvdata { - struct fb_info *fbinfo; - bool cmap_alloc; - - /* - * The address of the framebuffer in memory - */ - void *fb; - void *fb_aligned; - - /* - * Total size of vram including alignment allowance - */ - u32 total_vram_size; - - /* - * Fake palette of 16 colors - */ - u32 pseudo_palette[PALETTE_ENTRIES_NO]; - - int irq_req; - - /* - * Current pointer and bytes left to transfer with the PLIO - */ - void *xfer_ptr; - u32 bytes_to_xfer; - u32 busy; -}; - -static struct platform_device *ubicom32plio80_platform_device; - -/* - * ubicom32plio80_isr - */ -static int ubicom32plio80_isr(int irq, void *appdata) -{ - struct ubicom32plio80_drvdata *ud = (struct ubicom32plio80_drvdata *)appdata; - - if (!ud->bytes_to_xfer) { - ubicom32_disable_interrupt(TX_FIFO_INT(PLIO_PORT)); - PLIO_NBR->intmask.txfifo_wm = 0; - ud->busy = 0; - return IRQ_HANDLED; - } - - asm volatile ( - ".rept 8 \n\t" - "move.4 (%[fifo]), (%[data])4++ \n\t" - ".endr \n\t" - : [data] "+a" (ud->xfer_ptr) - : [fifo] "a" (&PLIO_NBR->tx_lo) - ); - - ud->bytes_to_xfer -= 32; - - return IRQ_HANDLED; -} - -/* - * ubicom32plio80_update - */ -static void ubicom32plio80_update(struct ubicom32plio80_drvdata *ud, u32 *fb) -{ - struct ubicom32_io_port *ri = (struct ubicom32_io_port *)RI; - struct ubicom32_io_port *rd = (struct ubicom32_io_port *)RD; - - ud->xfer_ptr = fb; - ud->bytes_to_xfer = (xres * yres * 2) - 64; - ud->busy = 1; - - ri->gpio_mask = 0; - rd->gpio_mask &= ~((1 << 4) | (1 << 2)); - - *(u32 *)(&PLIO_NBR->intclr) = ~0; - PLIO_NBR->intmask.txfifo_wm = 1; - PLIO_NBR->fifo_wm.tx = 8; - ubicom32_enable_interrupt(TX_FIFO_INT(PLIO_PORT)); - - asm volatile ( - ".rept 16 \n\t" - "move.4 (%[fifo]), (%[data])4++ \n\t" - ".endr \n\t" - : [data] "+a" (ud->xfer_ptr) - : [fifo] "a" (&PLIO_NBR->tx_lo) - ); -} - -/* - * ubicom32plio80_pan_display - * Pans the display to a given location. Supports only y direction panning. - */ -static int ubicom32plio80_pan_display(struct fb_var_screeninfo *var, struct fb_info *fbi) -{ - struct ubicom32plio80_drvdata *ud = (struct ubicom32plio80_drvdata *)fbi->par; - void *new_addr; - - /* - * Get the last y line that would be displayed. Since we don't support YWRAP, - * it must be less than our virtual y size. - */ - u32 lasty = var->yoffset + var->yres; - if (lasty > fbi->var.yres_virtual) { - /* - * We would fall off the end of our frame buffer if we panned here. - */ - return -EINVAL; - } - - if (var->xoffset) { - /* - * We don't support panning in the x direction - */ - return -EINVAL; - } - - /* - * Everything looks sane, go ahead and pan - * - * We have to calculate a new address for the VDC to look at - */ - new_addr = ud->fb_aligned + (var->yoffset * fbi->fix.line_length); - - return 0; -} - -/* - * ubicom32plio80_setcolreg - * Sets a color in our virtual palette - */ -static int ubicom32plio80_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *fbi) -{ - u32 *palette = fbi->pseudo_palette; - - if (regno >= PALETTE_ENTRIES_NO) { - return -EINVAL; - } - - /* - * We only use 8 bits from each color - */ - red >>= 8; - green >>= 8; - blue >>= 8; - - /* - * Convert any grayscale values - */ - if (fbi->var.grayscale) { - u16 gray = red + green + blue; - gray += (gray >> 2) + (gray >> 3) - (gray >> 7); - gray >>= 2; - if (gray > 255) { - gray = 255; - } - red = gray; - blue = gray; - green = gray; - } - - palette[regno] = (red << fbi->var.red.offset) | (green << fbi->var.green.offset) | - (blue << fbi->var.blue.offset); - - return 0; -} - -/* - * ubicom32plio80_mmap - */ -static int ubicom32plio80_mmap(struct fb_info *info, struct vm_area_struct *vma) -{ - struct ubicom32plio80_drvdata *ud = (struct ubicom32plio80_drvdata *)info->par; - - vma->vm_start = (unsigned long)(ud->fb_aligned); - - vma->vm_end = vma->vm_start + info->fix.smem_len; - - /* For those who don't understand how mmap works, go read - * Documentation/nommu-mmap.txt. - * For those that do, you will know that the VM_MAYSHARE flag - * must be set in the vma->vm_flags structure on noMMU - * Other flags can be set, and are documented in - * include/linux/mm.h - */ - - vma->vm_flags |= VM_MAYSHARE | VM_SHARED; - - return 0; -} - -/* - * ubicom32plio80_check_var - * Check the var, tweak it but don't change operational parameters. - */ -static int ubicom32plio80_check_var(struct fb_var_screeninfo *var, struct fb_info *info) -{ - struct ubicom32plio80_drvdata *ud = (struct ubicom32plio80_drvdata *)info->par; - u32 line_size = var->xres * (BITS_PER_PIXEL / 8); - - /* - * See if we can handle this bpp - */ - if (var->bits_per_pixel > BITS_PER_PIXEL) { - return -EINVAL; - } - var->bits_per_pixel = BITS_PER_PIXEL; - - /* - * See if we have enough memory to handle this resolution - */ - if ((line_size * var->yres * BITS_PER_PIXEL / 8) > ud->total_vram_size) { - return -EINVAL; - } - - var->xres_virtual = var->xres; - var->yres_virtual = ud->total_vram_size / line_size; - - var->red.length = 5; - var->green.length = 6; - var->green.offset = 5; - var->blue.length = 5; - var->transp.offset = var->transp.length = 0; - - if (bgr) { - var->red.offset = 0; - var->blue.offset = 11; - } else { - var->red.offset = 11; - var->blue.offset = 0; - } - - var->nonstd = 0; - var->height = -1; - var->width = -1; - var->vmode = FB_VMODE_NONINTERLACED; - var->sync = 0; - - return 0; -} - -/* - * ubicom32plio80_set_par - * Set the video mode according to info->var - */ -static int ubicom32plio80_set_par(struct fb_info *info) -{ - /* - * Anything changed? - */ - if ((xres == info->var.xres) && (yres == info->var.yres)) { - return 0; - } - - /* - * Implement changes - */ - xres = info->var.xres; - yres = info->var.yres; - info->fix.visual = FB_VISUAL_TRUECOLOR; - info->fix.xpanstep = 0; - info->fix.ypanstep = 1; - info->fix.line_length = xres * (BITS_PER_PIXEL / 8); - - return 0; -} - -/* - * ubicom32plio80_ops - * List of supported operations - */ -static struct fb_ops ubicom32plio80_ops = -{ - .owner = THIS_MODULE, - .fb_pan_display = ubicom32plio80_pan_display, - .fb_setcolreg = ubicom32plio80_setcolreg, - .fb_mmap = ubicom32plio80_mmap, - .fb_check_var = ubicom32plio80_check_var, - .fb_set_par = ubicom32plio80_set_par, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, -}; - -/* - * ubicom32plio80_release - */ -static int ubicom32plio80_release(struct device *dev) -{ - struct ubicom32plio80_drvdata *ud = dev_get_drvdata(dev); - - unregister_framebuffer(ud->fbinfo); - - if (ud->irq_req) { - free_irq(TX_FIFO_INT(PLIO_PORT), ud); - } - if (ud->cmap_alloc) { - fb_dealloc_cmap(&ud->fbinfo->cmap); - } - - if (ud->fb) { - kfree(ud->fb); - } - - framebuffer_release(ud->fbinfo); - dev_set_drvdata(dev, NULL); - - return 0; -} - -/* - * ubicom32plio80_platform_probe - */ -static int __init ubicom32plio80_platform_probe(struct platform_device *pdev) -{ - struct ubicom32plio80_drvdata *ud; - struct fb_info *fbinfo; - int rc; - size_t fbsize; - struct device *dev = &pdev->dev; - int offset; - - /* - * This is the minimum VRAM size - */ - fbsize = xres * yres * 2; - if (!vram_size) { - vram_size = (fbsize + 1023) / 1024; - } else { - if (fbsize > (vram_size * 1024)) { - dev_err(dev, "Not enough VRAM for display, need >= %u bytes\n", fbsize); - return -ENOMEM; // should be ebadparam? - } - } - - /* - * Allocate the framebuffer instance + our private data - */ - fbinfo = framebuffer_alloc(sizeof(struct ubicom32plio80_drvdata), &pdev->dev); - if (!fbinfo) { - dev_err(dev, "Not enough memory to allocate instance.\n"); - return -ENOMEM; - } - - /* - * Fill in our private data. - */ - ud = (struct ubicom32plio80_drvdata *)fbinfo->par; - ud->fbinfo = fbinfo; - dev_set_drvdata(dev, ud); - - /* - * Allocate and align the requested amount of VRAM - */ - ud->total_vram_size = (vram_size * 1024) + UBICOM32PLIO80_ALIGNMENT; - ud->fb = kmalloc(ud->total_vram_size, GFP_KERNEL); - if (ud->fb == NULL) { - dev_err(dev, "Couldn't allocate VRAM\n"); - rc = -ENOMEM; - goto fail; - } - - offset = (u32_t)ud->fb & (UBICOM32PLIO80_ALIGNMENT - 1); - if (!offset) { - ud->fb_aligned = ud->fb; - } else { - offset = UBICOM32PLIO80_ALIGNMENT - offset; - ud->fb_aligned = ud->fb + offset; - } - - /* - * Clear the entire frame buffer - */ - memset(ud->fb_aligned, 0, vram_size * 1024); - - /* - * Fill in the fb_var_screeninfo structure - */ - memset(&ubicom32plio80_var, 0, sizeof(ubicom32plio80_var)); - ubicom32plio80_var.bits_per_pixel = BITS_PER_PIXEL; - ubicom32plio80_var.red.length = 5; - ubicom32plio80_var.green.length = 6; - ubicom32plio80_var.green.offset = 5; - ubicom32plio80_var.blue.length = 5; - ubicom32plio80_var.activate = FB_ACTIVATE_NOW; - - if (bgr) { - ubicom32plio80_var.red.offset = 0; - ubicom32plio80_var.blue.offset = 11; - } else { - ubicom32plio80_var.red.offset = 11; - ubicom32plio80_var.blue.offset = 0; - } - - /* - * Fill in the fb_info structure - */ - ud->fbinfo->device = dev; - ud->fbinfo->screen_base = (void *)ud->fb_aligned; - ud->fbinfo->fbops = &ubicom32plio80_ops; - ud->fbinfo->fix = ubicom32plio80_fix; - ud->fbinfo->fix.smem_start = (u32)ud->fb_aligned; - ud->fbinfo->fix.smem_len = vram_size * 1024; - ud->fbinfo->fix.line_length = xres * 2; - ud->fbinfo->fix.mmio_start = (u32)ud; - ud->fbinfo->fix.mmio_len = sizeof(struct ubicom32plio80_drvdata); - - /* - * We support panning in the y direction only - */ - ud->fbinfo->fix.xpanstep = 0; - ud->fbinfo->fix.ypanstep = 1; - - ud->fbinfo->pseudo_palette = ud->pseudo_palette; - ud->fbinfo->flags = FBINFO_DEFAULT; - ud->fbinfo->var = ubicom32plio80_var; - ud->fbinfo->var.xres = xres; - ud->fbinfo->var.yres = yres; - - /* - * We cannot pan in the X direction, so xres_virtual is xres - * We can pan in the Y direction, so yres_virtual is vram_size / ud->fbinfo->fix.line_length - */ - ud->fbinfo->var.xres_virtual = xres; - ud->fbinfo->var.yres_virtual = (vram_size * 1024) / ud->fbinfo->fix.line_length; - - /* - * Allocate a color map - */ - rc = fb_alloc_cmap(&ud->fbinfo->cmap, PALETTE_ENTRIES_NO, 0); - if (rc) { - dev_err(dev, "Fail to allocate colormap (%d entries)\n", - PALETTE_ENTRIES_NO); - goto fail; - } - ud->cmap_alloc = true; - - /* - * Register new frame buffer - */ - rc = register_framebuffer(ud->fbinfo); - if (rc) { - dev_err(dev, "Could not register frame buffer\n"); - goto fail; - } - - /* - * request the PLIO IRQ - */ - rc = request_irq(TX_FIFO_INT(PLIO_PORT), ubicom32plio80_isr, IRQF_DISABLED, "ubicom32plio80", ud); - if (rc) { - dev_err(dev, "Could not request IRQ\n"); - goto fail; - } - ud->irq_req = 1; - - /* - * Clear any garbage out of the TX FIFOs (idif_txfifo_flush) - * - * cast through ubicom32_io_port to make sure the compiler does a word write - */ - ((struct ubicom32_io_port *)PLIO_NBR)->int_set = (1 << 18); - - /* - * Start up the state machine - */ - plio_init(&plio_fctl, &plio_config, (plio_sram_t *)ubicom32plio80_plio_fsm, sizeof(ubicom32plio80_plio_fsm)); - PLIO_NBR->fctl0.pfsm_cmd = 0; - - ubicom32plio80_update(ud, ud->fb_aligned); - - /* - * Tell the log we are here - */ - dev_info(dev, "fbaddr=%p align=%p, size=%uKB screen(%ux%u) virt(%ux%u)\n", - ud->fb, ud->fb_aligned, vram_size, ud->fbinfo->var.xres, ud->fbinfo->var.yres, - ud->fbinfo->var.xres_virtual, ud->fbinfo->var.yres_virtual); - - /* - * Success - */ - return 0; - -fail: - ubicom32plio80_release(dev); - return rc; -} - -/* - * ubicom32plio80_platform_remove - */ -static int ubicom32plio80_platform_remove(struct platform_device *pdev) -{ - dev_info(&(pdev->dev), "Ubicom32 FB Driver Remove\n"); - return ubicom32plio80_release(&pdev->dev); -} - -static struct platform_driver ubicom32plio80_platform_driver = { - .probe = ubicom32plio80_platform_probe, - .remove = ubicom32plio80_platform_remove, - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE, - }, -}; - -#ifndef MODULE -/* - * ubicom32plio80_setup - * Process kernel boot options - */ -static int __init ubicom32plio80_setup(char *options) -{ - char *this_opt; - - if (!options || !*options) { - return 0; - } - - while ((this_opt = strsep(&options, ",")) != NULL) { - if (!*this_opt) { - continue; - } - - if (!strncmp(this_opt, "vram_size=", 10)) { - vram_size = simple_strtoul(this_opt + 10, NULL, 0); - continue; - } - - if (!strncmp(this_opt, "bgr=", 4)) { - bgr = simple_strtoul(this_opt + 4, NULL, 0); - continue; - } - - if (!strncmp(this_opt, "xres=", 5)) { - xres = simple_strtoul(this_opt + 5, NULL, 0); - continue; - } - - if (!strncmp(this_opt, "yres=", 5)) { - yres = simple_strtoul(this_opt + 5, NULL, 0); - continue; - } - } - return 0; -} -#endif /* MODULE */ - -/* - * ubicom32plio80_init - */ -static int __devinit ubicom32plio80_init(void) -{ - int ret; - -#ifndef MODULE - /* - * Get kernel boot options (in 'video=ubicom32plio80:<options>') - */ - char *option = NULL; - - if (fb_get_options(DRIVER_NAME, &option)) { - return -ENODEV; - } - ubicom32plio80_setup(option); -#endif /* MODULE */ - - ret = platform_driver_register(&ubicom32plio80_platform_driver); - - if (!ret) { - ubicom32plio80_platform_device = platform_device_alloc(DRIVER_NAME, 0); - - if (ubicom32plio80_platform_device) - ret = platform_device_add(ubicom32plio80_platform_device); - else - ret = -ENOMEM; - - if (ret) { - platform_device_put(ubicom32plio80_platform_device); - platform_driver_unregister(&ubicom32plio80_platform_driver); - } - } - - return ret; -} -module_init(ubicom32plio80_init); - -/* - * ubicom32plio80_exit - */ -static void __exit ubicom32plio80_exit(void) -{ - platform_device_unregister(ubicom32plio80_platform_device); - platform_driver_unregister(&ubicom32plio80_platform_driver); -} -module_exit(ubicom32plio80_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Patrick Tjin <@ubicom.com>"); -MODULE_DESCRIPTION(DRIVER_DESCRIPTION); diff --git a/target/linux/ubicom32/files/drivers/video/ubicom32vfb.c b/target/linux/ubicom32/files/drivers/video/ubicom32vfb.c deleted file mode 100644 index 8478273d4c..0000000000 --- a/target/linux/ubicom32/files/drivers/video/ubicom32vfb.c +++ /dev/null @@ -1,603 +0,0 @@ -/* - * drivers/video/ubicom32vfb.c - * Ubicom32 virtual frame buffer driver - * - * (C) Copyright 2009, Ubicom, Inc. - * - * This file is part of the Ubicom32 Linux Kernel Port. - * - * The Ubicom32 Linux Kernel Port is free software: you can redistribute - * it and/or modify it under the terms of the GNU General Public License - * as published by the Free Software Foundation, either version 2 of the - * License, or (at your option) any later version. - * - * The Ubicom32 Linux Kernel Port is distributed in the hope that it - * will be useful, but WITHOUT ANY WARRANTY; without even the implied - * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See - * the GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with the Ubicom32 Linux Kernel Port. If not, - * see <http://www.gnu.org/licenses/>. - */ - -/* - * This driver was based on skeletonfb.c, Skeleton for a frame buffer device by - * Geert Uytterhoeven. - */ - -#include <linux/device.h> -#include <linux/module.h> -#include <linux/kernel.h> -#include <linux/version.h> -#include <linux/errno.h> -#include <linux/string.h> -#include <linux/mm.h> -#include <linux/fb.h> -#include <linux/init.h> -#include <linux/dma-mapping.h> -#include <linux/platform_device.h> -#include <linux/device.h> -#include <linux/uaccess.h> - -#define DRIVER_NAME "ubicom32vfb" -#define DRIVER_DESCRIPTION "Ubicom32 virtual frame buffer driver" - -#define PALETTE_ENTRIES_NO 16 - -/* - * Option variables - * - * vram_size: VRAM size in kilobytes, subject to alignment - */ -static int vram_size = 0; -module_param(vram_size, int, 0); -MODULE_PARM_DESC(vram_size, "VRAM size, in kilobytes to allocate, should be at least the size of one screen, subject to alignment"); - -static int xres = 320; -module_param(xres, int, 0); -MODULE_PARM_DESC(xres, "x (horizontal) resolution"); - -static int yres = 240; -module_param(yres, int, 0); -MODULE_PARM_DESC(yres, "y (vertical) resolution"); - -static int bgr = 0; -module_param(bgr, int, 0); -MODULE_PARM_DESC(bgr, "display is BGR (Blue is MSB)"); - -#define BITS_PER_PIXEL 16 - -/* - * Buffer alignment, must not be 0 - */ -#define UBICOM32VFB_ALIGNMENT 4 - -/* - * fb_fix_screeninfo defines the non-changeable properties of the VDC, depending on what mode it is in. - */ -static struct fb_fix_screeninfo ubicom32vfb_fix = { - .id = "Ubicom32", - .type = FB_TYPE_PACKED_PIXELS, - .visual = FB_VISUAL_TRUECOLOR, - .accel = FB_ACCEL_UBICOM32_VFB, -}; - -/* - * Filled in at probe time when we find out what the hardware supports - */ -static struct fb_var_screeninfo ubicom32vfb_var; - -/* - * Private data structure - */ -struct ubicom32vfb_drvdata { - struct fb_info *fbinfo; - bool cmap_alloc; - - /* - * The address of the framebuffer in memory - */ - void *fb; - void *fb_aligned; - - /* - * Total size of vram including alignment allowance - */ - u32 total_vram_size; - - /* - * Fake palette of 16 colors - */ - u32 pseudo_palette[PALETTE_ENTRIES_NO]; -}; - -static struct platform_device *ubicom32vfb_platform_device; - -/* - * ubicom32vfb_pan_display - * Pans the display to a given location. Supports only y direction panning. - */ -static int ubicom32vfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *fbi) -{ - struct ubicom32vfb_drvdata *ud = (struct ubicom32vfb_drvdata *)fbi->par; - void *new_addr; - - /* - * Get the last y line that would be displayed. Since we don't support YWRAP, - * it must be less than our virtual y size. - */ - u32 lasty = var->yoffset + var->yres; - if (lasty > fbi->var.yres_virtual) { - /* - * We would fall off the end of our frame buffer if we panned here. - */ - return -EINVAL; - } - - if (var->xoffset) { - /* - * We don't support panning in the x direction - */ - return -EINVAL; - } - - /* - * Everything looks sane, go ahead and pan - * - * We have to calculate a new address for the VDC to look at - */ - new_addr = ud->fb_aligned + (var->yoffset * fbi->fix.line_length); - - return 0; -} - -/* - * ubicom32vfb_setcolreg - * Sets a color in our virtual palette - */ -static int ubicom32vfb_setcolreg(unsigned regno, unsigned red, unsigned green, unsigned blue, unsigned transp, struct fb_info *fbi) -{ - u32 *palette = fbi->pseudo_palette; - - if (regno >= PALETTE_ENTRIES_NO) { - return -EINVAL; - } - - /* - * We only use 8 bits from each color - */ - red >>= 8; - green >>= 8; - blue >>= 8; - - /* - * Convert any grayscale values - */ - if (fbi->var.grayscale) { - u16 gray = red + green + blue; - gray += (gray >> 2) + (gray >> 3) - (gray >> 7); - gray >>= 2; - if (gray > 255) { - gray = 255; - } - red = gray; - blue = gray; - green = gray; - } - - palette[regno] = (red << fbi->var.red.offset) | (green << fbi->var.green.offset) | - (blue << fbi->var.blue.offset); - - return 0; -} - -/* - * ubicom32vfb_mmap - */ -static int ubicom32vfb_mmap(struct fb_info *info, struct vm_area_struct *vma) -{ - struct ubicom32vfb_drvdata *ud = (struct ubicom32vfb_drvdata *)info->par; - - vma->vm_start = (unsigned long)(ud->fb_aligned); - - vma->vm_end = vma->vm_start + info->fix.smem_len; - - /* For those who don't understand how mmap works, go read - * Documentation/nommu-mmap.txt. - * For those that do, you will know that the VM_MAYSHARE flag - * must be set in the vma->vm_flags structure on noMMU - * Other flags can be set, and are documented in - * include/linux/mm.h - */ - - vma->vm_flags |= VM_MAYSHARE | VM_SHARED; - - return 0; -} - -/* - * ubicom32vfb_check_var - * Check the var, tweak it but don't change operational parameters. - */ -static int ubicom32vfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) -{ - struct ubicom32vfb_drvdata *ud = (struct ubicom32vfb_drvdata *)info->par; - u32 line_size = var->xres * (BITS_PER_PIXEL / 8); - - /* - * See if we can handle this bpp - */ - if (var->bits_per_pixel > BITS_PER_PIXEL) { - return -EINVAL; - } - var->bits_per_pixel = BITS_PER_PIXEL; - - /* - * See if we have enough memory to handle this resolution - */ - if ((line_size * var->yres * BITS_PER_PIXEL / 8) > ud->total_vram_size) { - return -EINVAL; - } - - var->xres_virtual = var->xres; - var->yres_virtual = ud->total_vram_size / line_size; - - var->red.length = 5; - var->green.length = 6; - var->green.offset = 5; - var->blue.length = 5; - var->transp.offset = var->transp.length = 0; - - if (bgr) { - var->red.offset = 0; - var->blue.offset = 11; - } else { - var->red.offset = 11; - var->blue.offset = 0; - } - - var->nonstd = 0; - var->height = -1; - var->width = -1; - var->vmode = FB_VMODE_NONINTERLACED; - var->sync = 0; - - return 0; -} - -/* - * ubicom32vfb_set_par - * Set the video mode according to info->var - */ -static int ubicom32vfb_set_par(struct fb_info *info) -{ - /* - * Anything changed? - */ - if ((xres == info->var.xres) && (yres == info->var.yres)) { - return 0; - } - - /* - * Implement changes - */ - xres = info->var.xres; - yres = info->var.yres; - info->fix.visual = FB_VISUAL_TRUECOLOR; - info->fix.xpanstep = 0; - info->fix.ypanstep = 1; - info->fix.line_length = xres * (BITS_PER_PIXEL / 8); - - return 0; -} - -/* - * ubicom32vfb_ops - * List of supported operations - */ -static struct fb_ops ubicom32vfb_ops = -{ - .owner = THIS_MODULE, - .fb_pan_display = ubicom32vfb_pan_display, - .fb_setcolreg = ubicom32vfb_setcolreg, - .fb_mmap = ubicom32vfb_mmap, - .fb_check_var = ubicom32vfb_check_var, - .fb_set_par = ubicom32vfb_set_par, - .fb_fillrect = cfb_fillrect, - .fb_copyarea = cfb_copyarea, - .fb_imageblit = cfb_imageblit, -}; - -/* - * ubicom32vfb_release - */ -static int ubicom32vfb_release(struct device *dev) -{ - struct ubicom32vfb_drvdata *ud = dev_get_drvdata(dev); - - unregister_framebuffer(ud->fbinfo); - - if (ud->cmap_alloc) { - fb_dealloc_cmap(&ud->fbinfo->cmap); - } - - if (ud->fb) { - kfree(ud->fb); - } - - framebuffer_release(ud->fbinfo); - dev_set_drvdata(dev, NULL); - - return 0; -} - -/* - * ubicom32vfb_platform_probe - */ -static int __init ubicom32vfb_platform_probe(struct platform_device *pdev) -{ - struct ubicom32vfb_drvdata *ud; - struct fb_info *fbinfo; - int rc; - size_t fbsize; - struct device *dev = &pdev->dev; - int offset; - - /* - * This is the minimum VRAM size - */ - fbsize = xres * yres * 2; - if (!vram_size) { - vram_size = (fbsize + 1023) / 1024; - } else { - if (fbsize > (vram_size * 1024)) { - dev_err(dev, "Not enough VRAM for display, need >= %u bytes\n", fbsize); - return -ENOMEM; // should be ebadparam? - } - } - - /* - * Allocate the framebuffer instance + our private data - */ - fbinfo = framebuffer_alloc(sizeof(struct ubicom32vfb_drvdata), &pdev->dev); - if (!fbinfo) { - dev_err(dev, "Not enough memory to allocate instance.\n"); - return -ENOMEM; - } - - /* - * Fill in our private data. - */ - ud = (struct ubicom32vfb_drvdata *)fbinfo->par; - ud->fbinfo = fbinfo; - dev_set_drvdata(dev, ud); - - /* - * Allocate and align the requested amount of VRAM - */ - ud->total_vram_size = (vram_size * 1024) + UBICOM32VFB_ALIGNMENT; - ud->fb = kmalloc(ud->total_vram_size, GFP_KERNEL); - if (ud->fb == NULL) { - dev_err(dev, "Couldn't allocate VRAM\n"); - rc = -ENOMEM; - goto fail; - } - - offset = (u32_t)ud->fb & (UBICOM32VFB_ALIGNMENT - 1); - if (!offset) { - ud->fb_aligned = ud->fb; - } else { - offset = UBICOM32VFB_ALIGNMENT - offset; - ud->fb_aligned = ud->fb + offset; - } - - /* - * Clear the entire frame buffer - */ - memset(ud->fb_aligned, 0, vram_size * 1024); - - /* - * Fill in the fb_var_screeninfo structure - */ - memset(&ubicom32vfb_var, 0, sizeof(ubicom32vfb_var)); - ubicom32vfb_var.bits_per_pixel = BITS_PER_PIXEL; - ubicom32vfb_var.red.length = 5; - ubicom32vfb_var.green.length = 6; - ubicom32vfb_var.green.offset = 5; - ubicom32vfb_var.blue.length = 5; - ubicom32vfb_var.activate = FB_ACTIVATE_NOW; - - if (bgr) { - ubicom32vfb_var.red.offset = 0; - ubicom32vfb_var.blue.offset = 11; - } else { - ubicom32vfb_var.red.offset = 11; - ubicom32vfb_var.blue.offset = 0; - } - - /* - * Fill in the fb_info structure - */ - ud->fbinfo->device = dev; - ud->fbinfo->screen_base = (void *)ud->fb_aligned; - ud->fbinfo->fbops = &ubicom32vfb_ops; - ud->fbinfo->fix = ubicom32vfb_fix; - ud->fbinfo->fix.smem_start = (u32)ud->fb_aligned; - ud->fbinfo->fix.smem_len = vram_size * 1024; - ud->fbinfo->fix.line_length = xres * 2; - ud->fbinfo->fix.mmio_start = (u32)ud; - ud->fbinfo->fix.mmio_len = sizeof(struct ubicom32vfb_drvdata); - - /* - * We support panning in the y direction only - */ - ud->fbinfo->fix.xpanstep = 0; - ud->fbinfo->fix.ypanstep = 1; - - ud->fbinfo->pseudo_palette = ud->pseudo_palette; - ud->fbinfo->flags = FBINFO_DEFAULT; - ud->fbinfo->var = ubicom32vfb_var; - ud->fbinfo->var.xres = xres; - ud->fbinfo->var.yres = yres; - - /* - * We cannot pan in the X direction, so xres_virtual is xres - * We can pan in the Y direction, so yres_virtual is vram_size / ud->fbinfo->fix.line_length - */ - ud->fbinfo->var.xres_virtual = xres; - ud->fbinfo->var.yres_virtual = (vram_size * 1024) / ud->fbinfo->fix.line_length; - - /* - * Allocate a color map - */ - rc = fb_alloc_cmap(&ud->fbinfo->cmap, PALETTE_ENTRIES_NO, 0); - if (rc) { - dev_err(dev, "Fail to allocate colormap (%d entries)\n", - PALETTE_ENTRIES_NO); - goto fail; - } - ud->cmap_alloc = true; - - /* - * Register new frame buffer - */ - rc = register_framebuffer(ud->fbinfo); - if (rc) { - dev_err(dev, "Could not register frame buffer\n"); - goto fail; - } - - /* - * Tell the log we are here - */ - dev_info(dev, "fbaddr=%p align=%p, size=%uKB screen(%ux%u) virt(%ux%u)\n", - ud->fb, ud->fb_aligned, vram_size, ud->fbinfo->var.xres, ud->fbinfo->var.yres, - ud->fbinfo->var.xres_virtual, ud->fbinfo->var.yres_virtual); - - /* - * Success - */ - return 0; - -fail: - ubicom32vfb_release(dev); - return rc; -} - -/* - * ubicom32vfb_platform_remove - */ -static int ubicom32vfb_platform_remove(struct platform_device *pdev) -{ - dev_info(&(pdev->dev), "Ubicom32 FB Driver Remove\n"); - return ubicom32vfb_release(&pdev->dev); -} - -static struct platform_driver ubicom32vfb_platform_driver = { - .probe = ubicom32vfb_platform_probe, - .remove = ubicom32vfb_platform_remove, - .driver = { - .name = DRIVER_NAME, - .owner = THIS_MODULE, - }, -}; - -#ifndef MODULE -/* - * ubicom32vfb_setup - * Process kernel boot options - */ -static int __init ubicom32vfb_setup(char *options) -{ - char *this_opt; - - if (!options || !*options) { - return 0; - } - - while ((this_opt = strsep(&options, ",")) != NULL) { - if (!*this_opt) { - continue; - } - - if (!strncmp(this_opt, "vram_size=", 10)) { - vram_size = simple_strtoul(this_opt + 10, NULL, 0); - continue; - } - - if (!strncmp(this_opt, "bgr=", 4)) { - bgr = simple_strtoul(this_opt + 4, NULL, 0); - continue; - } - - if (!strncmp(this_opt, "xres=", 5)) { - xres = simple_strtoul(this_opt + 5, NULL, 0); - continue; - } - - if (!strncmp(this_opt, "yres=", 5)) { - yres = simple_strtoul(this_opt + 5, NULL, 0); - continue; - } - } - return 0; -} -#endif /* MODULE */ - -/* - * ubicom32vfb_init - */ -static int __devinit ubicom32vfb_init(void) -{ - int ret; - -#ifndef MODULE - /* - * Get kernel boot options (in 'video=ubicom32vfb:<options>') - */ - char *option = NULL; - - if (fb_get_options(DRIVER_NAME, &option)) { - return -ENODEV; - } - ubicom32vfb_setup(option); -#endif /* MODULE */ - - ret = platform_driver_register(&ubicom32vfb_platform_driver); - -#ifdef CONFIG_FB_UBICOM32_VIRTUAL_NOAUTO - return ret; -#else - if (!ret) { - ubicom32vfb_platform_device = platform_device_alloc(DRIVER_NAME, 0); - - if (ubicom32vfb_platform_device) - ret = platform_device_add(ubicom32vfb_platform_device); - else - ret = -ENOMEM; - - if (ret) { - platform_device_put(ubicom32vfb_platform_device); - platform_driver_unregister(&ubicom32vfb_platform_driver); - } - } - - return ret; -#endif -} -module_init(ubicom32vfb_init); - -/* - * ubicom32vfb_exit - */ -static void __exit ubicom32vfb_exit(void) -{ - platform_device_unregister(ubicom32vfb_platform_device); - platform_driver_unregister(&ubicom32vfb_platform_driver); -} -module_exit(ubicom32vfb_exit); - -MODULE_LICENSE("GPL"); -MODULE_AUTHOR("Patrick Tjin <@ubicom.com>"); -MODULE_DESCRIPTION(DRIVER_DESCRIPTION); |