linux-2.6.27: update keyboard and LCD patches for boc01
authorJeremy Lainé <jeremy.laine@m4x.org>
Tue, 6 Jan 2009 10:11:49 +0000 (11:11 +0100)
committerJeremy Lainé <jeremy.laine@m4x.org>
Tue, 6 Jan 2009 10:11:49 +0000 (11:11 +0100)
packages/linux/linux-2.6.27/boc01/012-081223-cy3218-btns.patch [moved from packages/linux/linux-2.6.27/boc01/012-081222-cy3218-btns.patch with 67% similarity]
packages/linux/linux-2.6.27/boc01/013-081224-lcd.patch [moved from packages/linux/linux-2.6.27/boc01/013-081216-lcd.patch with 70% similarity]
packages/linux/linux-2.6.27/boc01/defconfig
packages/linux/linux_2.6.27.bb

@@ -2,15 +2,16 @@ Index: linux-2.6.27/drivers/input/misc/cy3218-btns.c
 ===================================================================
 --- /dev/null
 +++ linux-2.6.27/drivers/input/misc/cy3218-btns.c
-@@ -0,0 +1,195 @@
+@@ -0,0 +1,301 @@
 +/*
 + * CAPSENSE Interface driver
 + *
 + *
-+ * Copyright (C) 2007, CenoSYS (www.cenosys.com).
++ * Copyright (C) 2008, CenoSYS (www.cenosys.com).
 + *
 + * Guillaume Ligneul <guillaume.ligneul@gmail.com>
 + * Jeremy Lainé <jeremy.laine@bolloretelecom.eu>
++ * Sylvain Giroudon <sylvain.giroudon@goobie.fr>
 + *
 + * This software program is licensed subject to the GNU General Public License
 + * (GPL).Version 2,June 1991, available at http://www.fsf.org/copyleft/gpl.html
@@ -21,23 +22,30 @@ Index: linux-2.6.27/drivers/input/misc/cy3218-btns.c
 +#include <linux/ioport.h>
 +#include <linux/module.h>
 +#include <linux/i2c.h>
++#include <linux/leds.h>
 +
 +static int capsense_attach_adapter(struct i2c_adapter *adapter);
 +static int capsense_detach_client(struct i2c_client *client);
 +
 +#define CAPSENSE_NAME "Capsense"
++
 +/* i2c configuration */
 +#define CAPSENSE_I2C_ADDR 0x25
 +// To debug (may be add in include/linux/i2c-id.h)
 +#define I2C_DRIVERID_CAPSENSE   98
++
 +#define BUTTONS_POLL_INTERVAL 30      /* msec */
-+#define CAP_STATE_GP0                 0x88
-+#define CAP_STATE_GP1                         0x89
++
++#define CAP_OUTPUT_PORT(port)   (0x04+(port))
++#define CAP_OP_SEL(port,bit)    (0x1C+(25*(port))+(5*(bit)))
++#define CAP_READ_STATUS(port) (0x88+(port))
++
 +#define MASK0                         0x10
 +#define MASK1                 0x4
 +#define MASK2                 0x8
 +#define MASK3                 0x1
 +
++#define CAP_NLEDS               5
 +
 +static int poll_interval = BUTTONS_POLL_INTERVAL;
 +module_param_named(poll, poll_interval, uint, 0);
@@ -57,13 +65,23 @@ Index: linux-2.6.27/drivers/input/misc/cy3218-btns.c
 +      .detach_client  = &capsense_detach_client,
 +};
 +
++struct cy3218_led {
++      struct led_classdev cdev;
++      struct cy3218 *capsense;
++      int port;
++      unsigned char mask;
++};
++
 +struct cy3218 {
 +      struct input_polled_dev *ipdev;
 +      struct i2c_client client;
 +      unsigned char key_state;
++      struct cy3218_led leds[CAP_NLEDS];
++      unsigned char led_state[2];
++      struct mutex mutex;
 +};
 +
-+unsigned short keymap[] = {
++static unsigned short keymap[] = {
 +      // GP0
 +      KEY_F1,
 +      KEY_ENTER,
@@ -73,6 +91,19 @@ Index: linux-2.6.27/drivers/input/misc/cy3218-btns.c
 +      KEY_UP,
 +};
 +
++struct cy3218_ledmap {
++      char *name;
++      int port, bit;
++};
++
++static struct cy3218_ledmap ledmap[CAP_NLEDS] = {
++      { "capsense:blue:back", 0, 1 },
++      { "capsense:blue:info", 1, 0 },
++      { "capsense:blue:down", 1, 1 },
++      { "capsense:blue:ok",   1, 2 },
++      { "capsense:blue:up",   1, 3 },
++};
++
 +static void handle_buttons(struct input_polled_dev *dev)
 +{
 +      struct cy3218 *capsense = dev->private;
@@ -81,16 +112,20 @@ Index: linux-2.6.27/drivers/input/misc/cy3218-btns.c
 +      u8 changed;
 +      int i;
 +
++      mutex_lock(&capsense->mutex);
++
 +      // read status
-+      port_value = i2c_smbus_read_byte_data(&capsense->client, CAP_STATE_GP0);
++      port_value = i2c_smbus_read_byte_data(&capsense->client, CAP_READ_STATUS(0));
 +      if (port_value & MASK0) new_state |= 0x01;
 +      if (port_value & MASK1) new_state |= 0x02;
 +      if (port_value & MASK2) new_state |= 0x04;
 +      if (port_value & MASK3) new_state |= 0x08;
 +
-+      port_value = i2c_smbus_read_byte_data(&capsense->client, CAP_STATE_GP1);
++      port_value = i2c_smbus_read_byte_data(&capsense->client, CAP_READ_STATUS(1));
 +      if (port_value & MASK0) new_state |= 0x10;
 +
++      mutex_unlock(&capsense->mutex);
++
 +      // update keyboard state
 +      changed = capsense->key_state ^ new_state;
 +      for (i = 0; i < ARRAY_SIZE(keymap); i++)
@@ -100,6 +135,69 @@ Index: linux-2.6.27/drivers/input/misc/cy3218-btns.c
 +      input_sync(dev->input);
 +}
 +
++
++static void
++capsense_led_set(struct led_classdev *led_cdev,
++               enum led_brightness value)
++{
++      struct cy3218_led *led = (struct cy3218_led *) led_cdev;
++      struct cy3218 *capsense = led->capsense;
++      int port = led->port;
++
++      if ( value )
++              capsense->led_state[port] |= led->mask;
++      else
++              capsense->led_state[port] &= ~led->mask;
++
++      mutex_lock(&capsense->mutex);
++      i2c_smbus_write_byte_data(&capsense->client, CAP_OUTPUT_PORT(port), capsense->led_state[port]);
++      mutex_unlock(&capsense->mutex);
++}
++
++static int
++capsense_led_init(struct cy3218 *capsense)
++{
++      int i;
++      int ret;
++
++      for (i = 0; i < CAP_NLEDS; i++) {
++              struct cy3218_led *led = &(capsense->leds[i]);
++
++              led->cdev.name = ledmap[i].name;
++              led->cdev.brightness_set = capsense_led_set;
++              led->capsense = capsense;
++              led->port = ledmap[i].port;
++              led->mask = (1 << ledmap[i].bit);
++
++              ret = led_classdev_register(&capsense->ipdev->input->dev, &led->cdev);
++              if ( ret < 0 )
++                      return -1;
++
++              i2c_smbus_write_byte_data(&capsense->client, CAP_OP_SEL(led->port, ledmap[i].bit), 0x00);
++      }
++
++      /* Switch all leds off */
++      capsense->led_state[0] = 0x00;
++      i2c_smbus_write_byte_data(&capsense->client, CAP_OUTPUT_PORT(0), 0x00);
++
++      capsense->led_state[1] = 0x00;
++      i2c_smbus_write_byte_data(&capsense->client, CAP_OUTPUT_PORT(1), 0x00);
++
++      return 0;
++}
++
++
++static void
++capsense_led_exit(struct cy3218 *capsense)
++{
++      int i;
++
++      for (i = 0; i < CAP_NLEDS; i++) {
++              led_classdev_unregister(&capsense->leds[i].cdev);
++      }
++}
++
++
 +static int
 +capsense_probe(struct i2c_adapter *adapter, int addr, int kind)
 +{
@@ -112,6 +210,8 @@ Index: linux-2.6.27/drivers/input/misc/cy3218-btns.c
 +              if (!capsense)
 +                      goto failout;
 +
++      mutex_init(&capsense->mutex);
++
 +      if (!i2c_check_functionality(adapter, I2C_FUNC_I2C)) {
 +              goto failout;
 +      }
@@ -156,8 +256,13 @@ Index: linux-2.6.27/drivers/input/misc/cy3218-btns.c
 +      if(rc)
 +              goto out_polled;
 +
++      if ( capsense_led_init(capsense) )
++              goto out_registered;
++
 +      return 0;
 +
++out_registered:
++      input_unregister_polled_device(ipdev);
 +out_polled:
 +      i2c_detach_client(&capsense->client);
 +out_attach:
@@ -177,6 +282,7 @@ Index: linux-2.6.27/drivers/input/misc/cy3218-btns.c
 +{
 +      struct cy3218 *capsense = i2c_get_clientdata(client);
 +
++      capsense_led_exit(capsense);
 +      input_unregister_polled_device(capsense->ipdev);
 +      i2c_detach_client(&capsense->client);
 +      input_free_polled_device(capsense->ipdev);
@@ -202,13 +308,14 @@ Index: linux-2.6.27/drivers/input/misc/Kconfig
 ===================================================================
 --- linux-2.6.27.orig/drivers/input/misc/Kconfig
 +++ linux-2.6.27/drivers/input/misc/Kconfig
-@@ -207,4 +207,12 @@ config HP_SDC_RTC
+@@ -207,4 +207,13 @@ config HP_SDC_RTC
          Say Y here if you want to support the built-in real time clock
          of the HP SDC controller.
  
 +config INPUT_CAPSENSE_BTNS
 +      tristate "CAPSENSE CY3218 button interface"
 +      select INPUT_POLLDEV
++      select LEDS_CLASS
 +      help
 +        To compile this driver as a module, choose M here: the
 +        module will be called cy3218-btns.
@@ -1,8 +1,8 @@
-Index: linux-2.6.26-NEW/drivers/video/Kconfig
+Index: linux-2.6.27/drivers/video/Kconfig
 ===================================================================
---- linux-2.6.26-NEW.orig/drivers/video/Kconfig
-+++ linux-2.6.26-NEW/drivers/video/Kconfig
-@@ -480,6 +480,17 @@ config FB_ARC
+--- linux-2.6.27.orig/drivers/video/Kconfig
++++ linux-2.6.27/drivers/video/Kconfig
+@@ -480,6 +480,19 @@ config FB_ARC
          this driver, say Y or M; otherwise say N. You must specify the
          GPIO IO address to be used for setting control and data.
  
@@ -13,6 +13,8 @@ Index: linux-2.6.26-NEW/drivers/video/Kconfig
 +      select FB_SYS_COPYAREA
 +      select FB_SYS_IMAGEBLIT
 +      select FB_SYS_FOPS
++      select FB_BACKLIGHT
++      select LCD_CLASS_DEVICE
 +      help
 +        This enables support for the Nova 7506 Monochrome LCD board. The board
 +        is based on the NT7506 lcd controller.
@@ -20,10 +22,10 @@ Index: linux-2.6.26-NEW/drivers/video/Kconfig
  config FB_ATARI
        bool "Atari native chipset support"
        depends on (FB = y) && ATARI
-Index: linux-2.6.26-NEW/drivers/video/Makefile
+Index: linux-2.6.27/drivers/video/Makefile
 ===================================================================
---- linux-2.6.26-NEW.orig/drivers/video/Makefile
-+++ linux-2.6.26-NEW/drivers/video/Makefile
+--- linux-2.6.27.orig/drivers/video/Makefile
++++ linux-2.6.27/drivers/video/Makefile
 @@ -13,8 +13,8 @@ fb-objs                           := $(f
  
  obj-$(CONFIG_VT)                += console/
@@ -35,15 +37,18 @@ Index: linux-2.6.26-NEW/drivers/video/Makefile
  obj-$(CONFIG_FB_CFB_FILLRECT)  += cfbfillrect.o
  obj-$(CONFIG_FB_CFB_COPYAREA)  += cfbcopyarea.o
  obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o
-Index: linux-2.6.26-NEW/drivers/video/N7506fb.c
+Index: linux-2.6.27/drivers/video/N7506fb.c
 ===================================================================
 --- /dev/null
-+++ linux-2.6.26-NEW/drivers/video/N7506fb.c
-@@ -0,0 +1,655 @@
++++ linux-2.6.27/drivers/video/N7506fb.c
+@@ -0,0 +1,728 @@
 +/*
 + * linux/drivers/video/N7506fb.c -- FB driver for Nova NT7506 monochrome LCD board
 + *
-+ * Copyright (C) 2008, Alexandre Coffignal <alexandre.coffignal@cenosys.com>
++ * Copyright (C) 2008, CenoSYS (www.cenosys.com).
++ *
++ * Alexandre Coffignal <alexandre.coffignal@cenosys.com>
++ * Sylvain Giroudon <sylvain.giroudon@goobie.fr>
 + *
 + * This file is subject to the terms and conditions of the GNU General Public
 + * License. See the file COPYING in the main directory of this archive for
@@ -77,11 +82,15 @@ Index: linux-2.6.26-NEW/drivers/video/N7506fb.c
 +#include <linux/interrupt.h>
 +#include <linux/fb.h>
 +#include <linux/init.h>
-+#include <linux/NT7506.h>
 +#include <linux/platform_device.h>
++#include <linux/backlight.h>
++#include <linux/lcd.h>
++#include <linux/NT7506.h>
 +
 +#include <linux/uaccess.h>
 +
++#define DRIVER_NAME "novafb"
++
 +#define floor8(a) (a&(~0x07))
 +#define floorXres(a,xres) (a&(~(xres - 1)))
 +#define iceil8(a) (((int)((a+7)/8))*8)
@@ -144,28 +153,28 @@ Index: linux-2.6.26-NEW/drivers/video/N7506fb.c
 +
 +#define LINE_LENGTH (LCD_WIDTH/8)    /* FB line size, 8 pixels per byte */
 +
-+#define CONTRASTE 0xF
-+#define FRAME_PER_SECOND 5
++#define DEFAULT_CONTRAST 20
++#define DEFAULT_FPS      5
 +
 +static struct resource *lcd_mem = NULL;
 +static void * _lcd_io = NULL;
 +static unsigned long tuhold;
 +struct fb_info *info;
 +static struct timer_list fb_timer;
-+static char _refresh;
-+static char _fps = FRAME_PER_SECOND;
-+static char _backlight=1;
++static char _refresh = 0;
++static char _fps = DEFAULT_FPS;
++static char _backlight = 1;
 +
 +struct novafb_par {
 +      atomic_t ref_count;
-+      unsigned char cslut[9];
 +      struct fb_info *info;
-+      unsigned int irq;
 +      spinlock_t lock;
++      struct lcd_device *lcd_dev;
++      int contrast;
 +};
 +
 +static struct fb_fix_screeninfo novafb_fix __initdata = {
-+      .id =           "novafb",
++      .id =           DRIVER_NAME,
 +      .type =         FB_TYPE_PACKED_PIXELS,
 +      .visual =       FB_VISUAL_MONO01,
 +      .xpanstep =     1,
@@ -185,6 +194,10 @@ Index: linux-2.6.26-NEW/drivers/video/N7506fb.c
 +};
 +
 +
++/*
++ * Low-level i/o primitives
++ */
++
 +static void NT7506_init_lcd(char ael);
 +
 +static void NT7506_writeb_ctl(unsigned char value)
@@ -232,7 +245,132 @@ Index: linux-2.6.26-NEW/drivers/video/N7506fb.c
 +      NT7506_writeb_ctl(NT_COL_LSB | (x & 0x0F) ); //Send low nibble
 +}
 +
-+/* main novafb functions */
++
++/*
++ * LCD device management
++ */
++
++static int
++novafb_lcd_get_contrast(struct lcd_device *lcd_dev)
++{
++      struct novafb_par *par = lcd_get_data(lcd_dev);
++      return par->contrast;
++}
++
++static int
++novafb_lcd_set_contrast(struct lcd_device *lcd_dev, int contrast)
++{
++      struct novafb_par *par = lcd_get_data(lcd_dev);
++
++      par->contrast = contrast;
++      NT7506_writeb_ctl(NT_ELEC_VOL); NT7506_writeb_ctl(par->contrast);
++
++      //printk(KERN_INFO DRIVER_NAME": contrast = %d\n", par->contrast);
++      return 0;
++}
++
++static struct lcd_ops novafb_lcd_ops = {
++      .get_contrast = novafb_lcd_get_contrast,
++      .set_contrast = novafb_lcd_set_contrast,
++};
++
++static void
++novafb_lcd_init(struct novafb_par *par)
++{
++      struct fb_info *info = par->info;
++      struct lcd_device *lcd_dev;
++
++      lcd_dev = lcd_device_register(DRIVER_NAME, info->dev, par, &novafb_lcd_ops);
++      if (IS_ERR(lcd_dev)) {
++              par->lcd_dev = NULL;
++              printk(KERN_WARNING DRIVER_NAME ": LCD device registration failed\n");
++              return;
++      }
++
++      par->lcd_dev = lcd_dev;
++      lcd_dev->props.max_contrast = 255;
++      par->contrast = DEFAULT_CONTRAST;
++      printk(KERN_INFO DRIVER_NAME ": LCD contrast management initialized\n");
++}
++
++static void
++novafb_lcd_exit(struct novafb_par *par)
++{
++      if ( par->lcd_dev ) {
++              lcd_device_unregister(par->lcd_dev);
++              par->lcd_dev = NULL;
++      }
++}
++
++
++/*
++ * Backlight device management
++ */
++
++static int
++novafb_bl_update_status(struct backlight_device *bd)
++{
++      _refresh = 0;
++
++      if (bd->props.power != FB_BLANK_UNBLANK ||
++          bd->props.fb_blank != FB_BLANK_UNBLANK)
++              _backlight = 0;
++      else
++              _backlight = bd->props.brightness;
++
++      _refresh = 1;
++
++      //printk(KERN_INFO DRIVER_NAME": backlight = %d\n", _backlight);
++      return 0;
++}
++
++static int
++novafb_bl_get_brightness(struct backlight_device *bd)
++{
++      return bd->props.brightness;
++}
++
++static struct backlight_ops novafb_bl_ops = {
++      .get_brightness = novafb_bl_get_brightness,
++      .update_status  = novafb_bl_update_status,
++};
++
++
++static void
++novafb_bl_init(struct novafb_par *par)
++{
++      struct fb_info *info = par->info;
++      struct backlight_device *bd;
++
++      bd = backlight_device_register(DRIVER_NAME, info->dev, par, &novafb_bl_ops);
++      if (IS_ERR(bd)) {
++              info->bl_dev = NULL;
++              printk(KERN_WARNING DRIVER_NAME ": Backlight device registration failed\n");
++              return;
++      }
++
++      info->bl_dev = bd;
++      bd->props.max_brightness = 1;
++      bd->props.power = FB_BLANK_UNBLANK;
++      bd->props.brightness = 1;
++      novafb_bl_update_status(bd);
++
++      printk(KERN_INFO DRIVER_NAME ": Backlight control initialized\n");
++}
++
++static void
++novafb_bl_exit(struct fb_info *info)
++{
++      if ( info->bl_dev ) {
++              backlight_device_unregister(info->bl_dev);
++              info->bl_dev = NULL;
++      }
++}
++
++
++/*
++ * Main frame buffer operations
++ */
 +
 +static int novafb_open(struct fb_info *info, int user)
 +{
@@ -254,9 +392,9 @@ Index: linux-2.6.26-NEW/drivers/video/N7506fb.c
 +static int novafb_pan_display(struct fb_var_screeninfo *var,
 +                              struct fb_info *info)
 +{
-+      if ((var->vmode & FB_VMODE_YWRAP) && (var->yoffset < LCD_HEIGHT)
-+              && (info->var.yres <= LCD_HEIGHT))
-+      {
++      if ( (var->vmode & FB_VMODE_YWRAP) &&
++           (var->yoffset < LCD_HEIGHT) &&
++           (info->var.yres <= LCD_HEIGHT) ) {
 +              NT7506_set_start_line(var->yoffset);
 +              info->var.yoffset = var->yoffset;
 +              return 0;
@@ -265,44 +403,36 @@ Index: linux-2.6.26-NEW/drivers/video/N7506fb.c
 +      return -EINVAL;
 +}
 +
-+static void novafb_lcd_update(struct novafb_par *par, unsigned int dx,
-+                      unsigned int dy, unsigned int w, unsigned int h)
++static void novafb_lcd_update(struct novafb_par *par)
 +{
-+      int bit,x,y,xfb,yfb,i;
-+      char mask=0;
-+      char dest[LCD_WIDTH * LCD_NPAGES];
-+      char * src;
-+      char value;
-+      src = (unsigned char __force *) par->info->screen_base;
-+      for(i=0;i<sizeof(dest);i++)
-+      {
-+              dest[i]=0;
-+      }
++      unsigned char *src = (unsigned char __force *) par->info->screen_base;
++      unsigned char dest[LCD_WIDTH * LCD_NPAGES];
++      int x, y;
++
 +      for (x = 0; x < LCD_WIDTH; x++) {
-+              xfb = x/8;
++              int xfb = x / 8;
 +
 +              for(y = 0; y < LCD_NPAGES; y++) {
-+                      yfb = y*8;
++                      int i = (y * LCD_WIDTH) + x;
++                      int yfb = y * 8;
++                      int bit;
++
++                      dest[i] = 0;
 +
-+                      for(bit=0;bit<8;yfb++,bit++)
-+                      {
-+                              mask = (1<<(7-(x%8)));
-+                              if(((src[yfb*LINE_LENGTH+xfb]&mask)))
-+                                      value=1;
-+                              else
-+                                      value=0;
++                      for (bit = 0; bit < 8; yfb++, bit++) {
++                              int ifb = (yfb * LINE_LENGTH) + xfb;
++                              unsigned char mask = (1 << (7-(x%8)));
++                              unsigned char value = (src[ifb] & mask) ? 1:0;
 +
-+                              dest[y*LCD_WIDTH+x]+= (value<<bit);
++                              dest[i] += (value<<bit);
 +                      }
 +              }
 +      }
 +
-+      for (y = 0; y < LCD_NPAGES; y++)
-+      {
++      for (y = 0; y < LCD_NPAGES; y++) {
 +              NT7506_set_yaddr(y);
 +              NT7506_set_xaddr(0);
-+              for (x = 0; x < LCD_WIDTH; x++)
-+              {
++              for (x = 0; x < LCD_WIDTH; x++) {
 +                      NT7506_writeb_data(dest[y*LCD_WIDTH+x]);
 +                      NT7506_writeb_data(0x00);
 +              }
@@ -312,9 +442,7 @@ Index: linux-2.6.26-NEW/drivers/video/N7506fb.c
 +
 +static void novafb_fillrect(struct fb_info *info,  const struct fb_fillrect *rect)
 +{
-+
-+//    sys_fillrect(info, rect);
-+
++      sys_fillrect(info, rect);
 +}
 +
 +
@@ -322,27 +450,16 @@ Index: linux-2.6.26-NEW/drivers/video/N7506fb.c
 +static void novafb_copyarea(struct fb_info *info,
 +                         const struct fb_copyarea *area)
 +{
-+//    sys_copyarea(info, area);
++      sys_copyarea(info, area);
 +}
 +
 +
 +static void novafb_imageblit(struct fb_info *info, const struct fb_image *image)
 +{
-+      struct novafb_par *par = info->par;
-+
-+      int xfb,yfb,i=0;
-+      char * src = (unsigned char __force *) par->info->screen_base;
-+
-+      for(yfb=image->dy;yfb<(image->height+image->dy);yfb++)
-+      {
-+              for(xfb=(image->dx)/8;xfb<(image->dx+image->width)/8;xfb++)
-+              {
-+                      src[yfb*16+xfb]=image->data[i++];
-+              }
-+      }
-+
++      sys_imageblit(info, image);
 +}
 +
++
 +/*
 + * this is the access path from userspace. they can seek and write to
 + * the fb. it's inefficient for them to do anything less than 128*8
@@ -351,40 +468,34 @@ Index: linux-2.6.26-NEW/drivers/video/N7506fb.c
 +static ssize_t novafb_write(struct fb_info *info, const char __user *buf,
 +                         size_t count, loff_t *ppos)
 +{
-+      unsigned long p;
-+      int err=-EINVAL;
-+      unsigned int fbmemlength   ;
-+      struct novafb_par *par;
-+      unsigned int xres;
-+      p = *ppos;
-+      par = info->par;
-+      xres = info->var.xres;
-+      fbmemlength = (xres * info->var.yres)/8;
++      unsigned long p = *ppos;
++      unsigned int fbmemlength;
++      int err = 0;
 +
-+      if (p > fbmemlength)
-+      {
-+              return -ENOSPC;
++      fbmemlength = (info->var.xres * info->var.yres)/8;
++
++      if ( p > fbmemlength ) {
++              return -EFBIG;
 +      }
-+      err = 0;
-+      if ((count + p) > fbmemlength) {
++
++      if ( (count + p) > fbmemlength ) {
 +              count = fbmemlength - p;
 +              err = -ENOSPC;
 +      }
 +
-+      if (count) {
-+              char *base_addr;
-+              base_addr = (char __force *)info->screen_base;
-+              count -= copy_from_user(base_addr + p, buf, count);
-+              *ppos += count;
-+              err = -EFAULT;
++      if ( count ) {
++              char *base_addr = (char __force *) info->screen_base;
++              if ( copy_from_user(base_addr + p, buf, count) )
++                      err = -EFAULT;
 +      }
-+      if (count)
-+      {
-+              return count;
-+      }
-+      return err;
++
++      if ( !err )
++              *ppos += count;
++
++      return err ? err : count;
 +}
 +
++
 +static int novafb_mmap(struct fb_info *info, struct vm_area_struct *vma)
 +{
 +      unsigned long off;
@@ -423,57 +534,22 @@ Index: linux-2.6.26-NEW/drivers/video/N7506fb.c
 +static int novafb_ioctl(struct fb_info *info,
 +                        unsigned int cmd, unsigned long arg)
 +{
-+      unsigned char contrast;
 +      unsigned char frame_rate;
-+      unsigned char backlight;
-+      switch (cmd)
-+      {
-+              case FBIO_FRAMERATE:
-+              {
-+
-+                      if (get_user(frame_rate, (unsigned char *)arg))
-+                              return -EFAULT;
-+                      printk(KERN_INFO "fb%d: framerate=%d Hz\n", info->node, frame_rate);
-+                      _fps=frame_rate;
-+                      return 0;
-+              }
-+              case FBIO_CONTRAST:
-+              {
-+                      _refresh=0;
-+                      if (get_user(contrast, (unsigned char *)arg))
-+                              return -EFAULT;
-+                      printk(KERN_INFO "fb%d: contrast=%d\n", info->node, contrast);
-+                      NT7506_writeb_ctl(NT_ELEC_VOL); NT7506_writeb_ctl(contrast);
-+                      _refresh=1;
-+                      return 0;
-+              }
-+              case FBIO_BACKLIGHT:
-+              {
-+                      _refresh=0;
-+                      if (get_user(backlight, (unsigned char *)arg))
-+                              return -EFAULT;
-+                      if(backlight)
-+                      {
-+                        printk(KERN_INFO "fb%d: Backlight ON\n", info->node);
-+                              _backlight=1;
-+                      }
-+                      else
-+                      {
-+                        printk(KERN_INFO "fb%d: Backlight OFF\n", info->node);
-+                              _backlight=0;
-+                      }
-+                      _refresh=1;
-+                      return 0;
-+
-+              }
 +
++      switch ( cmd ) {
++      case FBIO_FRAMERATE:
++              if (get_user(frame_rate, (unsigned char *)arg))
++                      return -EFAULT;
++              printk(KERN_INFO "fb%d: framerate=%d Hz\n", info->node, frame_rate);
++              _fps = frame_rate;
++              return 0;
 +
-+              default:
-+                      return -EINVAL;
++      default:
++              return -EINVAL;
 +      }
-+
 +}
 +
++
 +static struct fb_ops novafb_ops = {
 +      .owner          = THIS_MODULE,
 +      .fb_open        = novafb_open,
@@ -484,8 +560,8 @@ Index: linux-2.6.26-NEW/drivers/video/N7506fb.c
 +      .fb_fillrect    = novafb_fillrect,
 +      .fb_copyarea    = novafb_copyarea,
 +      .fb_imageblit   = novafb_imageblit,
-+      .fb_ioctl               = novafb_ioctl,
-+      .fb_mmap                =novafb_mmap,
++      .fb_ioctl       = novafb_ioctl,
++      .fb_mmap        novafb_mmap,
 +};
 +
 +
@@ -494,60 +570,50 @@ Index: linux-2.6.26-NEW/drivers/video/N7506fb.c
 +{
 +      struct novafb_par *par = info->par;
 +      if ( _refresh ) {
-+              novafb_lcd_update(par, 0, 0, LCD_WIDTH, LCD_HEIGHT);
++              novafb_lcd_update(par);
 +      }
 +
 +      fb_timer.expires = jiffies + (HZ/_fps);
 +      add_timer(&fb_timer);
 +}
 +
-+static int
-+__init novafb_probe(struct platform_device *dev)
++static int __init
++novafb_probe(struct platform_device *dev)
 +{
-+
 +      int retval = -ENOMEM;
-+      char * src;
-+      int i;
-+
 +      struct novafb_par *par;
 +      static unsigned char *videomemory;
 +      static  int videomemorysize;
 +
-+      NT7506_init_lcd(CONTRASTE);
++      NT7506_init_lcd(DEFAULT_CONTRAST);
 +
-+      videomemorysize = (LCD_WIDTH * LINE_LENGTH) * 2;
++      videomemorysize = (LINE_LENGTH * LCD_HEIGHT) * 2;
 +
 +      if (!(videomemory = kmalloc(videomemorysize,GFP_ATOMIC)))
-+              return retval;
++              goto failout;
 +      memset(videomemory, 0, videomemorysize);
 +
 +      info = framebuffer_alloc(sizeof(struct novafb_par), &dev->dev);
 +
 +      if (!info)
-+              goto err;
++              goto out_alloc;
 +      info->screen_base = (char __iomem *)videomemory;
 +      info->fbops = &novafb_ops;
 +
 +      info->var = novafb_var;
 +      info->fix = novafb_fix;
-+      info->fix.smem_start=(unsigned long)videomemory;
-+      info->fix.smem_len      = videomemorysize;
++      info->fix.smem_start = (unsigned long)videomemory;
++      info->fix.smem_len = videomemorysize;
 +
 +      par = info->par;
 +      par->info = info;
-+      par->cslut[0] = 0x00;
-+      par->cslut[1] = 0x06;
-+      src = (unsigned char __force *) par->info->screen_base;
-+      for(i=0;i<videomemorysize;i++)
-+      {
-+              src[i]=0;
-+      }
++
 +      info->flags = FBINFO_FLAG_DEFAULT;
 +      spin_lock_init(&par->lock);
 +      platform_set_drvdata(dev, info);
 +      retval = register_framebuffer(info);
 +      if (retval < 0)
-+              goto err1;
++              goto out_register;
 +
 +      init_timer(&fb_timer);
 +      fb_timer.function = novafb_refresh;
@@ -557,11 +623,18 @@ Index: linux-2.6.26-NEW/drivers/video/N7506fb.c
 +      printk(KERN_INFO
 +             "fb%d: nova frame buffer device, using %dK of video memory\n",
 +             info->node, videomemorysize >> 10);
++
++      /* Initialize backlight and contrast control (do not abort driver if it fails) */
++      novafb_bl_init(par);
++      novafb_lcd_init(par);
++
 +      return 0;
-+err1:
++
++out_register:
 +      framebuffer_release(info);
-+err:
++out_alloc:
 +      vfree(videomemory);
++failout:
 +      return retval;
 +}
 +
@@ -570,6 +643,8 @@ Index: linux-2.6.26-NEW/drivers/video/N7506fb.c
 +      struct fb_info *info = platform_get_drvdata(dev);
 +
 +      if (info) {
++              novafb_lcd_exit(info->par);
++              novafb_bl_exit(info);
 +              unregister_framebuffer(info);
 +              vfree((void __force *)info->screen_base);
 +              framebuffer_release(info);
@@ -581,7 +656,7 @@ Index: linux-2.6.26-NEW/drivers/video/N7506fb.c
 +      .probe  = novafb_probe,
 +      .remove = novafb_remove,
 +      .driver = {
-+              .name   = "novafb",
++              .name   = DRIVER_NAME,
 +      },
 +};
 +
@@ -604,7 +679,7 @@ Index: linux-2.6.26-NEW/drivers/video/N7506fb.c
 +      ret = platform_driver_register(&novafb_driver);
 +
 +      if (!ret) {
-+              novafb_device = platform_device_alloc("novafb", 0);
++              novafb_device = platform_device_alloc(DRIVER_NAME, 0);
 +              if (novafb_device)
 +              {
 +                      ret = platform_device_add(novafb_device);
@@ -695,11 +770,11 @@ Index: linux-2.6.26-NEW/drivers/video/N7506fb.c
 +MODULE_AUTHOR("Alexandre Coffignal");
 +MODULE_LICENSE("GPL");
 +
-Index: linux-2.6.26-NEW/include/linux/NT7506.h
+Index: linux-2.6.27/include/linux/NT7506.h
 ===================================================================
 --- /dev/null
-+++ linux-2.6.26-NEW/include/linux/NT7506.h
-@@ -0,0 +1,33 @@
++++ linux-2.6.27/include/linux/NT7506.h
+@@ -0,0 +1,31 @@
 +
 +/*
 + * (C) Copyright 2008
@@ -729,7 +804,5 @@ Index: linux-2.6.26-NEW/include/linux/NT7506.h
 +#define __LINUX_NOVAFB_H__
 +
 +#define FBIO_FRAMERATE                _IOR('f', 1, char)
-+#define FBIO_CONTRAST         _IOR('f', 2, char)
-+#define FBIO_BACKLIGHT                _IOR('f', 3, char)
 +
 +#endif
index bdca6aa..60bf9b9 100644 (file)
@@ -1302,7 +1302,7 @@ CONFIG_FB_SYS_IMAGEBLIT=y
 CONFIG_FB_SYS_FOPS=y
 # CONFIG_FB_SVGALIB is not set
 # CONFIG_FB_MACMODES is not set
-# CONFIG_FB_BACKLIGHT is not set
+CONFIG_FB_BACKLIGHT=y
 # CONFIG_FB_MODE_HELPERS is not set
 # CONFIG_FB_TILEBLITTING is not set
 
@@ -1340,7 +1340,14 @@ CONFIG_FB_NOVA=y
 # CONFIG_FB_FSL_DIU is not set
 # CONFIG_FB_IBM_GXT4500 is not set
 # CONFIG_FB_VIRTUAL is not set
-# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
+CONFIG_BACKLIGHT_LCD_SUPPORT=y
+CONFIG_LCD_CLASS_DEVICE=y
+# CONFIG_LCD_LTV350QV is not set
+# CONFIG_LCD_ILI9320 is not set
+# CONFIG_LCD_VGG2432A4 is not set
+# CONFIG_LCD_PLATFORM is not set
+CONFIG_BACKLIGHT_CLASS_DEVICE=y
+# CONFIG_BACKLIGHT_CORGI is not set
 
 #
 # Display device support
@@ -1438,7 +1445,7 @@ CONFIG_USB_OHCI_HCD_PCI=y
 CONFIG_USB_OHCI_BIG_ENDIAN_DESC=y
 CONFIG_USB_OHCI_BIG_ENDIAN_MMIO=y
 CONFIG_USB_OHCI_LITTLE_ENDIAN=y
-CONFIG_USB_UHCI_HCD=y
+# CONFIG_USB_UHCI_HCD is not set
 # CONFIG_USB_SL811_HCD is not set
 # CONFIG_USB_R8A66597_HCD is not set
 
index e490afe..cf064d3 100644 (file)
@@ -1,5 +1,7 @@
 require linux.inc
 
+PR = "r1"
+
 # Mark archs/machines that this kernel supports
 DEFAULT_PREFERENCE = "-1"
 DEFAULT_PREFERENCE_boc01 = "1"
@@ -18,8 +20,8 @@ SRC_URI_append_boc01 = "\
        file://008-081208-spi.patch;patch=1 \
        file://010-081208-mii.patch;patch=1 \
        file://011-081218-gpio.patch;patch=1 \
-       file://012-081222-cy3218-btns.patch;patch=1 \
-       file://013-081216-lcd.patch;patch=1 \
+       file://012-081223-cy3218-btns.patch;patch=1 \
+       file://013-081224-lcd.patch;patch=1 \
        "
 
 SRC_URI_append_progear = "file://progear-bl.patch;patch=1\