opensimpad: MMC support + better support for SinusPad and 128M SIMpad
authorFrederic Bompart <frederic@unknown.openembedded.org>
Fri, 11 Nov 2005 14:51:32 +0000 (14:51 +0000)
committerOpenEmbedded Project <openembedded-devel@lists.openembedded.org>
Fri, 11 Nov 2005 14:51:32 +0000 (14:51 +0000)
- There's now a config options to build the kernel for 128Mb SIMpad
  (as there was one for the SinusPad)
- The .bb files automatically turn on these options depending on the
  total memory available.
- The MMC driver was made by Clement Ballabriga <clement@asso.ups-tlse.fr>
  and Guylhem Aznar <simpad@externe.net>.
  Adding an MMC card (internal or external) to the SIMpad is described
  on these pages:
  http://externe.net/zaurus/simpad-bluetooth/
  http://www.iral.com/~albertr/linux/simpad/mmc/

packages/linux/opensimpad-2.4.25-vrs2-pxa1-jpm1/defconfig-simpad
packages/linux/opensimpad-2.4.27-vrs1-pxa1-jpm1/defconfig-simpad
packages/linux/opensimpad-64+0_2.4.27-vrs1-pxa1-jpm1.bb
packages/linux/opensimpad/mmc-spi.patch [new file with mode: 0644]
packages/linux/opensimpad/support-128mb-flash.patch [deleted file]
packages/linux/opensimpad/support-128mb-ram.patch [new file with mode: 0644]
packages/linux/opensimpad_2.4.25-vrs2-pxa1-jpm1.bb
packages/linux/opensimpad_2.4.27-vrs1-pxa1-jpm1.bb

index 90791c6..dd67df8 100644 (file)
@@ -102,7 +102,6 @@ CONFIG_ARCH_SA1100=y
 # CONFIG_SA1100_SHANNON is not set
 # CONFIG_SA1100_SHERMAN is not set
 CONFIG_SA1100_SIMPAD=y
-# CONFIG_SA1100_SIMPAD_SINUSPAD is not set
 # CONFIG_SA1100_SIMPUTER is not set
 # CONFIG_SA1100_PFS168 is not set
 # CONFIG_SA1100_VICTOR is not set
@@ -304,10 +303,6 @@ CONFIG_MTD_SA1100=y
 #
 # CONFIG_MTD_PMC551 is not set
 # CONFIG_MTD_SLRAM is not set
-CONFIG_MTD_MTDRAM=y
-CONFIG_MTDRAM_TOTAL_SIZE=32768
-CONFIG_MTDRAM_ERASE_SIZE=1
-CONFIG_MTDRAM_ABS_POS=C2000000
 # CONFIG_MTD_BLKMTD is not set
 
 #
@@ -332,6 +327,7 @@ CONFIG_MTDRAM_ABS_POS=C2000000
 #
 # Block devices
 #
+CONFIG_BLK_DEV_MMC=m
 # CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_DEV_XD is not set
 # CONFIG_PARIDE is not set
index 88d334a..ebeab96 100644 (file)
@@ -102,7 +102,6 @@ CONFIG_ARCH_SA1100=y
 # CONFIG_SA1100_SHANNON is not set
 # CONFIG_SA1100_SHERMAN is not set
 CONFIG_SA1100_SIMPAD=y
-# CONFIG_SA1100_SIMPAD_SINUSPAD is not set
 # CONFIG_SA1100_SIMPUTER is not set
 # CONFIG_SA1100_PFS168 is not set
 # CONFIG_SA1100_VICTOR is not set
@@ -305,10 +304,6 @@ CONFIG_MTD_SA1100=y
 #
 # CONFIG_MTD_PMC551 is not set
 # CONFIG_MTD_SLRAM is not set
-CONFIG_MTD_MTDRAM=y
-CONFIG_MTDRAM_TOTAL_SIZE=32768
-CONFIG_MTDRAM_ERASE_SIZE=1
-CONFIG_MTDRAM_ABS_POS=C2000000
 # CONFIG_MTD_BLKMTD is not set
 
 #
@@ -333,6 +328,7 @@ CONFIG_MTDRAM_ABS_POS=C2000000
 #
 # Block devices
 #
+CONFIG_BLK_DEV_MMC=m
 # CONFIG_BLK_DEV_FD is not set
 # CONFIG_BLK_DEV_XD is not set
 # CONFIG_PARIDE is not set
index fb12c70..5bd4c85 100644 (file)
@@ -1,5 +1,11 @@
+# to use another configuration, duplicate this file, change the sizes,
+# change the filename accordingly, and add the followin line to local.conf:
+# PREFERRED_PROVIDER_virtual/kernel_kernel24 = "opensimpad-64+0"
+
 SECTION = "kernel"
 include opensimpad_${PV}.bb
 
+# fraction of the memory (in Mb) used for RAM
 SIMPAD_MEM = "64"
+# fraction of the memory (in Mb) used as a ramdisk
 SIMPAD_RD = "0"
diff --git a/packages/linux/opensimpad/mmc-spi.patch b/packages/linux/opensimpad/mmc-spi.patch
new file mode 100644 (file)
index 0000000..1841b45
--- /dev/null
@@ -0,0 +1,885 @@
+
+#
+# Patch managed by http://www.holgerschurig.de/patcher.html
+#
+
+--- /dev/null
++++ linux-2.4.27/drivers/block/mmc.c
+@@ -0,0 +1,857 @@
++/*
++ * Copyright (c) ClĂ©ment Ballabriga, 2005 - GPL
++ * Copyright (c) Guylhem Aznar, 2005 - GPL
++ *
++ * Please check http://externe.net/zaurus/simpad-bluetooth reference design first.
++ *
++ * Based on Madsuk/Rohde work on a MMC driver for the WRT54G.
++ *
++ * This is an ugly hack of a driver. I am surprised if it ever works!
++ * So please use a real driver or contribute one to the 2.4/2.6 mmc framework
++ */
++
++#include <linux/stddef.h>
++#include <linux/delay.h>
++#include <linux/timer.h>
++#include <linux/module.h>
++#include <linux/mm.h>
++#include <linux/init.h>
++#include <linux/fs.h>
++#include <linux/blkpg.h>
++#include <linux/hdreg.h>
++#include <linux/major.h>
++
++#include <asm/hardware.h>
++#include <asm/uaccess.h>
++#include <asm/io.h>
++
++/*
++ * *******************************************************************
++ *
++ *                This is the only configurable part.
++ *
++ * *******************************************************************
++ *
++ */
++
++// #define DEBUG 1
++
++#define DEVICE_NAME "mmc"
++#define DEVICE_NR(device) (MINOR(device))
++#define DEVICE_ON(device)
++#define DEVICE_OFF(device)
++#define MAJOR_NR 121
++
++/* Let that include where it is or compilation fails on INIT_REQUEST/CURRENT */
++
++#include <linux/blk.h>
++
++MODULE_AUTHOR("Guylhem Aznar <mmc-driver @externe.net>");
++MODULE_DESCRIPTION("Driver for MMC/SD-Cards in SPI mode by GPIO");
++MODULE_SUPPORTED_DEVICE("Simpad");
++MODULE_LICENSE("GPL");
++
++/* Registers should be architecture independant - but it's not ! */
++
++#define MAP_START 0x90040000
++#define MAP_SIZE  0x00001000
++
++#define MY_GPLR 0
++#define MY_GPDR 1
++#define MY_GPSR 2
++#define MY_GPCR 3
++#define MY_GRER 4
++#define MY_GFER 5
++#define MY_GEDR 6
++#define MY_GAFR 7
++
++/*
++ * If you are using different GPIOs in your hardware hack, you must
++ * first make sure they are unused for other functions and then
++ * configure them here.
++ *
++ * On the simpad I use spare pins from the UART1 (internal serial port):
++ * - DCD (in)  : GPIO 23 : DO
++ * - DTR (out) : GPIO 07 : CS 
++ * - RI  (in)  : GPIO 19 : CLK
++ * - DSR (in)  : GPIO 06 : DI
++ *
++ * Don't worry about in/out original function - the GPIOs will be
++ * reprogrammed.
++ */
++
++#define GPIO_SD_DO  23
++#define GPIO_SD_CS  7
++#define GPIO_SD_CLK 19
++#define GPIO_SD_DI  6
++
++/*
++ * *******************************************************************
++ *
++ *               Do not change anything below !
++ *
++ * *******************************************************************
++ *
++ */
++
++
++/* GPIO states */
++#define LOW 0
++#define HIGH 1
++
++#define INPUT 0
++#define OUTPUT 1
++
++#define PRESENT 1
++#define ABSENT 0
++
++typedef unsigned int uint32;
++typedef unsigned long u32_t;
++typedef unsigned short u16_t;
++typedef unsigned char u8_t;
++
++/* we have only one device */
++static int hd_sizes[1 << 6];
++static int hd_blocksizes[1 << 6];
++static int hd_hardsectsizes[1 << 6];
++static int hd_maxsect[1 << 6];
++static struct hd_struct hd[1 << 6];
++
++static struct timer_list mmc_timer;
++
++/* start with no card */
++static int mmc_media_detect = 0;
++static int mmc_media_changed = 1;
++
++extern struct gendisk hd_gendisk;
++
++/* Use only one global device */
++typedef struct gpio_s gpio_t;
++struct gpio_s {
++    volatile u32_t *base;
++};
++
++static gpio_t gp = {
++      (void *) io_p2v(MAP_START)
++};
++
++/*
++ * *******************************************************************
++ *
++ *             Begin GPIO hardware access functions.
++ *
++ * *******************************************************************
++ *
++ */
++
++gpio_t *gpio_open(void)
++{
++    static gpio_t tmp;
++    tmp.base = (void *) io_p2v(MAP_START);
++    return (&tmp);
++}
++
++void gpio_setdir(gpio_t * g, int num, int dir)
++{
++    if (dir == 1) {
++      g->base[MY_GPDR] |= (1 << num);
++    } else {
++      g->base[MY_GPDR] &= ~(1 << num);
++
++    }
++}
++
++void gpio_setalt(gpio_t * g, int num, int alt)
++{
++    if (alt == 1) {
++      g->base[MY_GAFR] |= (1 << num);
++    } else {
++      g->base[MY_GAFR] &= ~(1 << num);
++    }
++}
++
++int gpio_getdir(gpio_t * g, int num)
++{
++    return ((g->base[MY_GPDR] & (1 << num)) ? 1 : 0);
++}
++
++int gpio_getalt(gpio_t * g, int num)
++{
++    return ((g->base[MY_GAFR] & (1 << num)) ? 1 : 0);
++}
++
++static int gpio_read(gpio_t * g, int num)
++{
++      int what;
++    
++      what=(g->base[MY_GPLR] & (1 << num)) ? 1 : 0;
++      
++#ifdef DEBUG
++    if (num == GPIO_SD_DO) {
++          printk ("GPIO_SD_DO read: %u\n", what);
++    }
++#endif
++    return (what);
++}
++
++static int gpio_write(gpio_t * g, int num, int val)
++{
++#ifdef DEBUG
++      int check;
++#endif
++      
++    if (val == 1) {
++      g->base[MY_GPSR] = 1 << num;
++    } else {
++      g->base[MY_GPCR] = 1 << num;
++    }
++#ifdef DEBUG
++    check=gpio_read(g,num);
++    if (check != val)
++    {
++        printk ("Error while write to %d: found %d after writing %d\n",num, check, val);
++      return (1);
++    }
++    else return(0);
++#endif
++
++}
++
++/*
++ * *******************************************************************
++ *
++ *             Begin SPI hardware access functions.
++ *
++ * *******************************************************************
++ *
++ */
++static int mmc_spi_media_detect(void)
++{
++// FIXME: add card detection/test by SPI
++
++    return 1;
++}
++
++static int mmc_spi_hardware_init(void)
++{
++    /*unsigned char gpio_outen;*/
++
++    printk("mmc: GPIO init\n");
++
++    /* Now global
++     * gp = gpio_open(); */
++
++    /* Cut existing functions */
++    gpio_setalt(&gp, GPIO_SD_CLK, 0);
++    gpio_setalt(&gp, GPIO_SD_DI, 0);
++    gpio_setalt(&gp, GPIO_SD_DO, 0);
++    gpio_setalt(&gp, GPIO_SD_CS, 0);
++
++    /* Remap directions */
++    gpio_setdir(&gp, GPIO_SD_CLK, OUTPUT);
++    gpio_setdir(&gp, GPIO_SD_DI, OUTPUT);
++    gpio_setdir(&gp, GPIO_SD_DO, INPUT);
++    gpio_setdir(&gp, GPIO_SD_CS, OUTPUT);
++
++    printk("mmc: initialising MMC\n");
++
++    /* Start */
++    gpio_write(&gp, GPIO_SD_CLK, LOW);
++    gpio_write(&gp, GPIO_SD_DI, LOW);
++    gpio_write(&gp, GPIO_SD_CS, LOW);
++    return 0;
++}
++
++/* return what has been read, write the parameter */
++
++static unsigned char mmc_spi_readwrite(unsigned char data_out)
++{
++    int i;
++    unsigned char result = 0/*, tmp_data = 0*/;
++
++    for (i = 0; i < 8; i++) {
++      if (data_out & (0x01 << (7 - i)))
++          gpio_write(&gp, GPIO_SD_DI, HIGH);
++      else
++          gpio_write(&gp, GPIO_SD_DI, LOW);
++
++      gpio_write(&gp, GPIO_SD_CLK, HIGH);
++
++      result <<= 1;
++
++      if (gpio_read(&gp, GPIO_SD_DO) == 1)
++          result |= 1;
++
++      gpio_write(&gp, GPIO_SD_CLK, LOW);
++    }
++
++    return (result);
++}
++
++static int mmc_spi_card_init(void)
++{
++    unsigned char result = 0;
++    short i, j;
++    unsigned long flags;
++
++    save_flags(flags);
++    cli();
++
++    printk("GPIO_SD_CS dir: %u alt: %u\n", gpio_getdir(&gp, GPIO_SD_CS), gpio_getalt(&gp, GPIO_SD_CS));
++    printk("GPIO_SD_DI dir: %u alt: %u\n", gpio_getdir(&gp, GPIO_SD_DI), gpio_getalt(&gp, GPIO_SD_DI));
++    printk("GPIO_SD_DO dir: %u alt: %u\n", gpio_getdir(&gp, GPIO_SD_DO), gpio_getalt(&gp, GPIO_SD_DO));
++    printk("GPIO_SD_CS dir: %u alt: %u\n", gpio_getdir(&gp, GPIO_SD_CLK), gpio_getalt(&gp, GPIO_SD_CLK));
++    
++    printk("mmc: card init 1/2\n");
++    gpio_write(&gp, GPIO_SD_CS, HIGH);
++    for (i = 0; i < 20; i++)
++      mmc_spi_readwrite(0xff);
++
++    gpio_write(&gp, GPIO_SD_CS, LOW);
++
++    mmc_spi_readwrite(0x40);
++    for (i = 0; i < 4; i++)
++      mmc_spi_readwrite(0x00);
++    mmc_spi_readwrite(0x95);
++    for (i = 0; i < 8; i++) {
++      result = mmc_spi_readwrite(0xff);
++      if (result == 0x01)
++          break;
++    }
++    gpio_write(&gp, GPIO_SD_CS, HIGH);
++    mmc_spi_readwrite(0xff);
++    if (result != 0x01) {
++        printk("mmc: card init %d error\n", result);
++      restore_flags(flags);
++      return (1);
++    }
++
++    printk("mmc: card init 2/2\n");
++    for (j = 0; j < 10000; j++) {
++      gpio_write(&gp, GPIO_SD_CS, LOW);
++
++      mmc_spi_readwrite(0x41);
++      for (i = 0; i < 4; i++)
++          mmc_spi_readwrite(0x00);
++      mmc_spi_readwrite(0xff);
++      for (i = 0; i < 8; i++) {
++          result = mmc_spi_readwrite(0xff);
++          if (result == 0x00)
++              break;
++      }
++      gpio_write(&gp, GPIO_SD_CS, HIGH);
++      mmc_spi_readwrite(0xff);
++      if (result == 0x00) {
++          restore_flags(flags);
++          printk("mmc: card init 3/3\n");
++          return (0);
++      }
++    }
++    restore_flags(flags);
++
++    return (2);
++}
++
++
++static int mmc_spi_card_config(void)
++{
++    unsigned char result = 0;
++    short i;
++    unsigned char csd[32];
++    unsigned int c_size;
++    unsigned int c_size_mult;
++    unsigned int mult;
++    unsigned int read_bl_len;
++    unsigned int blocknr = 0;
++    unsigned int block_len = 0;
++    unsigned int size = 0;
++
++    gpio_write(&gp, GPIO_SD_CS, LOW);
++    for (i = 0; i < 4; i++)
++      mmc_spi_readwrite(0xff);
++    mmc_spi_readwrite(0x49);
++    for (i = 0; i < 4; i++)
++      mmc_spi_readwrite(0x00);
++    mmc_spi_readwrite(0xff);
++    for (i = 0; i < 8; i++) {
++      result = mmc_spi_readwrite(0xff);
++      if (result == 0x00)
++          break;
++    }
++    if (result != 0x00) {
++      gpio_write(&gp, GPIO_SD_CS, HIGH);
++      mmc_spi_readwrite(0xff);
++      return (1);
++    }
++    for (i = 0; i < 8; i++) {
++      result = mmc_spi_readwrite(0xff);
++      if (result == 0xfe)
++          break;
++    }
++    if (result != 0xfe) {
++      gpio_write(&gp, GPIO_SD_CS, HIGH);
++      mmc_spi_readwrite(0xff);
++      return (2);
++    }
++    for (i = 0; i < 16; i++) {
++      result = mmc_spi_readwrite(0xff);
++      csd[i] = result;
++    }
++    for (i = 0; i < 2; i++) {
++      result = mmc_spi_readwrite(0xff);
++    }
++    gpio_write(&gp, GPIO_SD_CS, HIGH);
++    mmc_spi_readwrite(0xff);
++    if (result == 0x00)
++      return (3);
++
++    c_size = csd[8] + csd[7] * 256 + (csd[6] & 0x03) * 256 * 256;
++    c_size >>= 6;
++    c_size_mult = csd[10] + (csd[9] & 0x03) * 256;
++    c_size_mult >>= 7;
++    read_bl_len = csd[5] & 0x0f;
++    mult = 1;
++    mult <<= c_size_mult + 2;
++    blocknr = (c_size + 1) * mult;
++    block_len = 1;
++    block_len <<= read_bl_len;
++    size = block_len * blocknr;
++    size >>= 10;
++
++    for (i = 0; i < (1 << 6); i++) {
++      hd_blocksizes[i] = 1024;
++      hd_hardsectsizes[i] = block_len;
++      hd_maxsect[i] = 256;
++    }
++    hd_sizes[0] = size;
++    hd[0].nr_sects = blocknr;
++
++
++    printk("Size = %d, hardsectsize = %d, sectors = %d\n",
++         size, block_len, blocknr);
++
++    return 0;
++}
++
++
++/*
++ * *******************************************************************
++ *
++ *             End of SPI hardware access functions.
++ *
++ * *******************************************************************
++ */
++
++
++static int mmc_write_block(unsigned int dest_addr, unsigned char *data)
++{
++    unsigned int address;
++    unsigned char result = 0;
++    unsigned char ab0, ab1, ab2, ab3;
++    int i;
++
++    address = dest_addr;
++
++    ab3 = 0xff & (address >> 24);
++    ab2 = 0xff & (address >> 16);
++    ab1 = 0xff & (address >> 8);
++    ab0 = 0xff & address;
++    gpio_write(&gp, GPIO_SD_CS, LOW);
++    for (i = 0; i < 4; i++)
++      mmc_spi_readwrite(0xff);
++    mmc_spi_readwrite(0x58);
++    mmc_spi_readwrite(ab3);           /* msb */
++    mmc_spi_readwrite(ab2);
++    mmc_spi_readwrite(ab1);
++    mmc_spi_readwrite(ab0);           /* lsb */
++    mmc_spi_readwrite(0xff);
++    for (i = 0; i < 8; i++) {
++      result = mmc_spi_readwrite(0xff);
++      if (result == 0x00)
++          break;
++    }
++    if (result != 0x00) {
++      gpio_write(&gp, GPIO_SD_CS, HIGH);
++      mmc_spi_readwrite(0xff);
++      return (1);
++    }
++
++    mmc_spi_readwrite(0xfe);
++    for (i = 0; i < 512; i++)
++      mmc_spi_readwrite(data[i]);
++    for (i = 0; i < 2; i++)
++      mmc_spi_readwrite(0xff);
++
++    for (i = 0; i < 1000000; i++) {
++      result = mmc_spi_readwrite(0xff);
++      if (result == 0xff)
++          break;
++    }
++    if (result != 0xff) {
++      gpio_write(&gp, GPIO_SD_CS, HIGH);
++      mmc_spi_readwrite(0xff);
++      return (3);
++    }
++    gpio_write(&gp, GPIO_SD_CS, HIGH);
++    mmc_spi_readwrite(0xff);
++    return (0);
++}
++
++static int mmc_read_block(unsigned char *data, unsigned int src_addr)
++{
++    unsigned int address;
++    unsigned char result = 0;
++    unsigned char ab0, ab1, ab2, ab3;
++    int i;
++
++    address = src_addr;
++
++    ab3 = 0xff & (address >> 24);
++    ab2 = 0xff & (address >> 16);
++    ab1 = 0xff & (address >> 8);
++    ab0 = 0xff & address;
++
++    gpio_write(&gp, GPIO_SD_CS, LOW);
++    for (i = 0; i < 4; i++)
++      mmc_spi_readwrite(0xff);
++    mmc_spi_readwrite(0x51);
++    mmc_spi_readwrite(ab3);           /* msb */
++    mmc_spi_readwrite(ab2);
++    mmc_spi_readwrite(ab1);
++    mmc_spi_readwrite(ab0);           /* lsb */
++
++    mmc_spi_readwrite(0xff);
++    for (i = 0; i < 8; i++) {
++      result = mmc_spi_readwrite(0xff);
++      if (result == 0x00)
++          break;
++    }
++    if (result != 0x00) {
++      gpio_write(&gp, GPIO_SD_CS, HIGH);
++      mmc_spi_readwrite(0xff);
++      return (1);
++    }
++    for (i = 0; i < 100000; i++) {
++      result = mmc_spi_readwrite(0xff);
++      if (result == 0xfe)
++          break;
++    }
++    if (result != 0xfe) {
++      gpio_write(&gp, GPIO_SD_CS, HIGH);
++      mmc_spi_readwrite(0xff);
++      return (2);
++    }
++    for (i = 0; i < 512; i++) {
++      result = mmc_spi_readwrite(0xff);
++      data[i] = result;
++    }
++    for (i = 0; i < 2; i++) {
++      result = mmc_spi_readwrite(0xff);
++    }
++    gpio_write(&gp, GPIO_SD_CS, HIGH);
++    mmc_spi_readwrite(0xff);
++
++    return (0);
++}
++
++static void mmc_request(request_queue_t * q)
++{
++    unsigned int mmc_address;
++    unsigned char *buffer_address;
++    int nr_sectors;
++    int i;
++    int cmd;
++    int result, code;
++
++    (void) q;
++    while (1) {
++      code = 1;               // Default is success
++      INIT_REQUEST;
++      mmc_address =
++          (CURRENT->sector +
++           hd[MINOR(CURRENT->rq_dev)].start_sect) * hd_hardsectsizes[0];
++      buffer_address = CURRENT->buffer;
++      nr_sectors = CURRENT->current_nr_sectors;
++      cmd = CURRENT->cmd;
++      if (((CURRENT->sector + CURRENT->current_nr_sectors +
++            hd[MINOR(CURRENT->rq_dev)].start_sect) > hd[0].nr_sects)
++          || (mmc_media_detect == 0)) {
++          code = 0;
++      } else if (cmd == READ) {
++          spin_unlock_irq(&io_request_lock);
++          for (i = 0; i < nr_sectors; i++) {
++              result = mmc_read_block(buffer_address, mmc_address);
++              if (result != 0) {
++                  printk("mmc: error %d in mmc_read_block\n", result);
++                  code = 0;
++                  break;
++              } else {
++                  mmc_address += hd_hardsectsizes[0];
++                  buffer_address += hd_hardsectsizes[0];
++              }
++          }
++          spin_lock_irq(&io_request_lock);
++      } else if (cmd == WRITE) {
++          spin_unlock_irq(&io_request_lock);
++          for (i = 0; i < nr_sectors; i++) {
++              result = mmc_write_block(mmc_address, buffer_address);
++              if (result != 0) {
++                  printk("mmc: error %d in mmc_write_block\n", result);
++                  code = 0;
++                  break;
++              } else {
++                  mmc_address += hd_hardsectsizes[0];
++                  buffer_address += hd_hardsectsizes[0];
++              }
++          }
++          spin_lock_irq(&io_request_lock);
++      } else {
++          code = 0;
++      }
++      end_request(code);
++    }
++}
++
++
++static int mmc_open(struct inode *inode, struct file *filp)
++{
++    /*int device;*/
++    (void) filp;
++    mmc_media_detect = mmc_spi_media_detect();
++
++    if (mmc_media_detect == 0)
++      return -ENODEV;
++
++#if defined(MODULE)
++    MOD_INC_USE_COUNT;
++#endif
++    return 0;
++}
++
++static int mmc_release(struct inode *inode, struct file *filp)
++{
++    (void) filp;
++    fsync_dev(inode->i_rdev);
++    invalidate_buffers(inode->i_rdev);
++
++#if defined(MODULE)
++    MOD_DEC_USE_COUNT;
++#endif
++    return 0;
++}
++
++static int mmc_revalidate(kdev_t dev)
++{
++    int target, max_p, start, i;
++
++    mmc_media_detect = mmc_spi_media_detect();
++
++    if (mmc_media_detect == 0)
++      return -ENODEV;
++
++    target = DEVICE_NR(dev);
++
++    max_p = hd_gendisk.max_p;
++    start = target << 6;
++    for (i = max_p - 1; i >= 0; i--) {
++      int minor = start + i;
++      invalidate_device(MKDEV(MAJOR_NR, minor), 1);
++      hd_gendisk.part[minor].start_sect = 0;
++      hd_gendisk.part[minor].nr_sects = 0;
++    }
++
++    grok_partitions(&hd_gendisk, target, 1 << 6, hd_sizes[0] * 2);
++
++    return 0;
++}
++
++static int mmc_ioctl(struct inode *inode, struct file *filp,
++                   unsigned int cmd, unsigned long arg)
++{
++    if (!inode || !inode->i_rdev)
++      return -EINVAL;
++
++    switch (cmd) {
++    case BLKGETSIZE:
++      return put_user(hd[MINOR(inode->i_rdev)].nr_sects,
++                      (unsigned long *) arg);
++    case BLKGETSIZE64:
++      return put_user((u64) hd[MINOR(inode->i_rdev)].
++                      nr_sects, (u64 *) arg);
++    case BLKRRPART:
++      if (!capable(CAP_SYS_ADMIN))
++          return -EACCES;
++
++      return mmc_revalidate(inode->i_rdev);
++    case HDIO_GETGEO:
++      {
++          struct hd_geometry *loc, g;
++          loc = (struct hd_geometry *) arg;
++          if (!loc)
++              return -EINVAL;
++          g.heads = 4;
++          g.sectors = 16;
++          g.cylinders = hd[0].nr_sects / (4 * 16);
++          g.start = hd[MINOR(inode->i_rdev)].start_sect;
++          return copy_to_user(loc, &g, sizeof(g)) ? -EFAULT : 0;
++      }
++    default:
++      return blk_ioctl(inode->i_rdev, cmd, arg);
++    }
++}
++
++
++/*
++static int mmc_check_media_change(kdev_t dev)
++{
++    (void) dev;
++    if (mmc_media_changed == 1) {
++      mmc_media_changed = 0;
++      return 1;
++    } else
++      return 0;
++}
++*/
++
++static struct block_device_operations mmc_bdops = {
++  open:mmc_open,
++  release:mmc_release,
++  ioctl:mmc_ioctl,
++/* FIXME: add media change support
++ *    check_media_change: mmc_check_media_change,
++ *    revalidate: mmc_revalidate,
++ */
++};
++
++static struct gendisk hd_gendisk = {
++  major:MAJOR_NR,
++  major_name:DEVICE_NAME,
++  minor_shift:6,
++  max_p:1 << 6,
++  part:hd,
++  sizes:hd_sizes,
++  fops:&mmc_bdops,
++};
++
++static int mmc_init(void)
++{
++    int result;
++
++    result = mmc_spi_hardware_init();
++
++    if (result != 0) {
++      printk("mmc: error %d in mmc_spi_hardware_init\n", result);
++      return -1;
++    }
++
++    result = mmc_spi_card_init();
++    if (result != 0) {
++      // Give it an extra shot
++      result = mmc_spi_card_init();
++      if (result != 0) {
++          printk("mmc: error %d in mmc_card_init\n", result);
++          return -1;
++      }
++    }
++
++    memset(hd_sizes, 0, sizeof(hd_sizes));
++    result = mmc_spi_card_config();
++    if (result != 0) {
++      printk("mmc: error %d in mmc_card_config\n", result);
++      return -1;
++    }
++
++
++    blk_size[MAJOR_NR] = hd_sizes;
++
++    memset(hd, 0, sizeof(hd));
++    hd[0].nr_sects = hd_sizes[0] * 2;
++
++    blksize_size[MAJOR_NR] = hd_blocksizes;
++    hardsect_size[MAJOR_NR] = hd_hardsectsizes;
++    max_sectors[MAJOR_NR] = hd_maxsect;
++
++    hd_gendisk.nr_real = 1;
++
++    register_disk(&hd_gendisk, MKDEV(MAJOR_NR, 0), 1 << 6,
++                &mmc_bdops, hd_sizes[0] * 2);
++
++    return 0;
++}
++
++static void mmc_exit(void)
++{
++    blk_size[MAJOR_NR] = NULL;
++    blksize_size[MAJOR_NR] = NULL;
++    hardsect_size[MAJOR_NR] = NULL;
++    max_sectors[MAJOR_NR] = NULL;
++    hd[0].nr_sects = 0;
++}
++
++static void mmc_check_media(void)
++{
++    int old_state, new_state;
++    int result;
++
++    old_state = mmc_media_detect;
++    new_state = mmc_spi_media_detect();
++
++    if (old_state != new_state) {
++      mmc_media_changed = 1;
++      if (new_state == PRESENT) {
++          result = mmc_init();
++          if (result != 0)
++              printk("mmc: error %d in mmc_init\n", result);
++      } else {
++          mmc_exit();
++      }
++    }
++
++    /* del_timer(&mmc_timer);
++       mmc_timer.expires = jiffies + 10*HZ;
++       add_timer(&mmc_timer); */
++}
++
++static int __init mmc_driver_init(void)
++{
++    int result;
++
++    result = devfs_register_blkdev(MAJOR_NR, DEVICE_NAME, &mmc_bdops);
++    if (result < 0) {
++      printk(KERN_WARNING "mmc: can't get major %d\n", MAJOR_NR);
++      return result;
++    }
++
++    blk_init_queue(BLK_DEFAULT_QUEUE(MAJOR_NR), mmc_request);
++
++    mmc_check_media();
++
++    /*init_timer(&mmc_timer);
++       mmc_timer.expires = jiffies + HZ;
++       mmc_timer.function = (void *)mmc_check_media;
++       add_timer(&mmc_timer); */
++
++
++    read_ahead[MAJOR_NR] = 8;
++    add_gendisk(&hd_gendisk);
++
++
++    return 0;
++}
++
++static void __exit mmc_driver_exit(void)
++{
++    int i;
++    del_timer(&mmc_timer);
++
++    for (i = 0; i < (1 << 6); i++)
++      fsync_dev(MKDEV(MAJOR_NR, i));
++
++    blk_cleanup_queue(BLK_DEFAULT_QUEUE(MAJOR_NR));
++    del_gendisk(&hd_gendisk);
++    devfs_unregister_blkdev(MAJOR_NR, DEVICE_NAME);
++    mmc_exit();
++}
++
++module_init(mmc_driver_init);
++module_exit(mmc_driver_exit);
+--- linux-2.4.27/drivers/block/Config.in~mmc-spi
++++ linux-2.4.27/drivers/block/Config.in
+@@ -4,6 +4,7 @@
+ mainmenu_option next_comment
+ comment 'Block devices'
++tristate 'MMC SPI driver' CONFIG_BLK_DEV_MMC
+ tristate 'Normal floppy disk support' CONFIG_BLK_DEV_FD
+ if [ "$CONFIG_AMIGA" = "y" ]; then
+    tristate 'Amiga floppy support' CONFIG_AMIGA_FLOPPY
+--- linux-2.4.27/drivers/block/Makefile~mmc-spi
++++ linux-2.4.27/drivers/block/Makefile
+@@ -15,6 +15,7 @@
+ obj-y := ll_rw_blk.o blkpg.o genhd.o elevator.o
+ obj-$(CONFIG_MAC_FLOPPY)      += swim3.o
++obj-$(CONFIG_BLK_DEV_MMC)     += mmc.o
+ obj-$(CONFIG_BLK_DEV_FD)      += floppy.o
+ obj-$(CONFIG_AMIGA_FLOPPY)    += amiflop.o
+ obj-$(CONFIG_ATARI_FLOPPY)    += ataflop.o
diff --git a/packages/linux/opensimpad/support-128mb-flash.patch b/packages/linux/opensimpad/support-128mb-flash.patch
deleted file mode 100644 (file)
index 2a6b1bd..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-
-#
-# Patch managed by http://www.holgerschurig.de/patcher.html
-#
-
---- linux-2.4.27/arch/arm/mach-sa1100/simpad.c~support-128mb-flash
-+++ linux-2.4.27/arch/arm/mach-sa1100/simpad.c
-@@ -83,11 +83,16 @@
- {
- #ifdef CONFIG_SA1100_SIMPAD_SINUSPAD
-       SET_BANK( 0, 0xc0000000, 32*1024*1024 );
-+      mi->nr_banks = 1;
- #else
-       SET_BANK( 0, 0xc0000000, 64*1024*1024 );
--#endif
-       mi->nr_banks = 1;
-+#endif
-+#ifdef CONFIG_SA1100_SIMPAD_128M
-+      SET_BANK( 1, 0xc8000000, 64*1024*1024 );
-+      mi->nr_banks = 2;
-+#endif
-       setup_ramdisk( 1, 0, 0, 8192 );
-       setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 );
- }
diff --git a/packages/linux/opensimpad/support-128mb-ram.patch b/packages/linux/opensimpad/support-128mb-ram.patch
new file mode 100644 (file)
index 0000000..f0cde06
--- /dev/null
@@ -0,0 +1,35 @@
+
+#
+# Patch managed by http://www.holgerschurig.de/patcher.html
+#
+
+--- linux-2.4.27/arch/arm/mach-sa1100/simpad.c~support-128mb-ram
++++ linux-2.4.27/arch/arm/mach-sa1100/simpad.c
+@@ -83,11 +83,16 @@
+ {
+ #ifdef CONFIG_SA1100_SIMPAD_SINUSPAD
+       SET_BANK( 0, 0xc0000000, 32*1024*1024 );
++      mi->nr_banks = 1;
+ #else
+       SET_BANK( 0, 0xc0000000, 64*1024*1024 );
+-#endif
+       mi->nr_banks = 1;
++#endif
++#ifdef CONFIG_SA1100_SIMPAD_128M
++      SET_BANK( 1, 0xc8000000, 64*1024*1024 );
++      mi->nr_banks = 2;
++#endif
+       setup_ramdisk( 1, 0, 0, 8192 );
+       setup_initrd( __phys_to_virt(0xc0800000), 4*1024*1024 );
+ }
+--- linux-2.4.27/arch/arm/config.in~support-128mb-ram
++++ linux-2.4.27/arch/arm/config.in
+@@ -130,6 +130,7 @@
+ dep_bool '  Simpad' CONFIG_SA1100_SIMPAD $CONFIG_ARCH_SA1100
+ if [ "$CONFIG_SA1100_SIMPAD" = "y" ]; then
+    bool '    T-Sinus PAD' CONFIG_SA1100_SIMPAD_SINUSPAD
++   bool '    Simpad with 128Mb RAM' CONFIG_SA1100_SIMPAD_128M
+ fi
+ dep_bool '  Simputer' CONFIG_SA1100_SIMPUTER $CONFIG_ARCH_SA1100
+ dep_bool '  Tulsa' CONFIG_SA1100_PFS168 $CONFIG_ARCH_SA1100
index a707910..6970dd9 100644 (file)
@@ -1,12 +1,12 @@
 DESCRIPTION = "Linux kernel for the SIEMENS SIMpad family of devices."
-MAINTAINER = "Michael 'Mickey' Lauer <mickey@Vanille.de>"
+MAINTAINER = "Frederic Devernay <frederic.devernay@m4x.org>"
 SECTION = "kernel"
 LICENSE = "GPL"
 KV = "${@bb.data.getVar('PV',d,True).split('-')[0]}"
 VRSV = "${@bb.data.getVar('PV',d,True).split('-')[1]}"
 PXAV = "${@bb.data.getVar('PV',d,True).split('-')[2]}"
 JPMV = "${@bb.data.getVar('PV',d,True).split('-')[3]}"
-PR = "r19"
+PR = "r20"
 
 FILESPATH = "${FILE_DIRNAME}/opensimpad-${PV}:${FILE_DIRNAME}/opensimpad:${FILE_DIRNAME}/files:${FILE_DIRNAME}"
 
@@ -26,7 +26,9 @@ SRC_URI = "ftp://ftp.kernel.org/pub/linux/kernel/v2.4/linux-${KV}.tar.bz2 \
            file://simpad-apm.diff;patch=1;pnum=0 \
            file://simpad-ts-noninput.patch;patch=1 \
            file://simpad-pm-updates.patch;patch=1;pnum=0 \
-           file://support-128mb-flash.patch;patch=1"
+           file://support-128mb-ram.patch;patch=1 \
+           file://mmc-spi.patch;patch=1 \
+"
 
 # apply this when we have a patch that allows building with gcc 3.x:
 # SRC_URI_append = file://gcc-3.3.patch;patch=1
@@ -65,6 +67,18 @@ do_configure() {
                 echo "CONFIG_MTDRAM_ERASE_SIZE=1"           >> ${S}/.config
                 echo "CONFIG_MTDRAM_ABS_POS=$addr"          >> ${S}/.config
         fi
+       if [ "$total" == "128" ]
+        then
+                echo "CCONFIG_SA1100_SIMPAD_128M=y"           >> ${S}/.config
+        else
+                echo "# CONFIG_SA1100_SIMPAD_128M is not set" >> ${S}/.config
+       fi
+       if [ "$total" == "32" ]
+        then
+                echo "CONFIG_SA1100_SIMPAD_SINUSPAD=y"            >> ${S}/.config
+        else
+                echo "# CONFIG_SA1100_SIMPAD_SINUSPAD is not set" >> ${S}/.config
+       fi
        echo "CONFIG_CMDLINE=\"${CMDLINE} mem=${mem}M\"" >> ${S}/.config
         oe_runmake oldconfig
 }
index 0183f36..95e483a 100644 (file)
@@ -1,5 +1,5 @@
 DESCRIPTION = "Linux kernel for the SIEMENS SIMpad family of devices."
-MAINTAINER = "Michael 'Mickey' Lauer <mickey@Vanille.de>"
+MAINTAINER = "Frederic Devernay <frederic.devernay@m4x.org>"
 SECTION = "kernel"
 LICENSE = "GPL"
 KV = "${@bb.data.getVar('PV',d,True).split('-')[0]}"
@@ -7,7 +7,7 @@ VRSV = "${@bb.data.getVar('PV',d,True).split('-')[1]}"
 PXAV = "${@bb.data.getVar('PV',d,True).split('-')[2]}"
 JPMV = "${@bb.data.getVar('PV',d,True).split('-')[3]}"
 USBV= "usb20040610"
-PR = "r1"
+PR = "r2"
 
 FILESPATH = "${FILE_DIRNAME}/opensimpad-${PV}:${FILE_DIRNAME}/opensimpad:${FILE_DIRNAME}/files:${FILE_DIRNAME}"
 
@@ -28,11 +28,12 @@ SRC_URI = "ftp://ftp.kernel.org/pub/linux/kernel/v2.4/linux-${KV}.tar.bz2 \
            file://simpad-apm.patch;patch=1 \
            file://simpad-ts-noninput.patch;patch=1 \
            file://simpad-pm-updates.patch;patch=1 \
-           file://support-128mb-flash.patch;patch=1 \
+           file://support-128mb-ram.patch;patch=1 \
            file://simpad-proc-sys-board.patch;patch=1 \
            file://simpad-serial.patch;patch=1 \
            file://mppe-20040216.patch;patch=1 \
            file://sa1100-usb-tcl1.patch;patch=1 \
+           file://mmc-spi.patch;patch=1 \
 "
 # This applies right after the jpm patch but is useless until we
 # have sa1100_udc.c
@@ -75,6 +76,18 @@ do_configure() {
                 echo "CONFIG_MTDRAM_ERASE_SIZE=1"           >> ${S}/.config
                 echo "CONFIG_MTDRAM_ABS_POS=$addr"          >> ${S}/.config
         fi
+       if [ "$total" == "128" ]
+        then
+                echo "CONFIG_SA1100_SIMPAD_128M=y"            >> ${S}/.config
+        else
+                echo "# CONFIG_SA1100_SIMPAD_128M is not set" >> ${S}/.config
+       fi
+       if [ "$total" == "32" ]
+        then
+                echo "CONFIG_SA1100_SIMPAD_SINUSPAD=y"            >> ${S}/.config
+        else
+                echo "# CONFIG_SA1100_SIMPAD_SINUSPAD is not set" >> ${S}/.config
+       fi
        echo "CONFIG_CMDLINE=\"${CMDLINE} mem=${mem}M\"" >> ${S}/.config
         oe_runmake oldconfig
 }