diff options
Diffstat (limited to 'arch/mips/tx4938/toshiba_rbtx4938/setup.c')
-rw-r--r-- | arch/mips/tx4938/toshiba_rbtx4938/setup.c | 171 |
1 files changed, 94 insertions, 77 deletions
diff --git a/arch/mips/tx4938/toshiba_rbtx4938/setup.c b/arch/mips/tx4938/toshiba_rbtx4938/setup.c index 12b9f4f..361d89a 100644 --- a/arch/mips/tx4938/toshiba_rbtx4938/setup.c +++ b/arch/mips/tx4938/toshiba_rbtx4938/setup.c @@ -14,13 +14,13 @@ #include <linux/init.h> #include <linux/types.h> #include <linux/ioport.h> -#include <linux/proc_fs.h> #include <linux/delay.h> #include <linux/interrupt.h> #include <linux/console.h> #include <linux/pci.h> #include <linux/pm.h> #include <linux/platform_device.h> +#include <linux/clk.h> #include <asm/wbflush.h> #include <asm/reboot.h> @@ -29,13 +29,15 @@ #include <asm/uaccess.h> #include <asm/io.h> #include <asm/bootinfo.h> -#include <asm/gpio.h> #include <asm/tx4938/rbtx4938.h> #ifdef CONFIG_SERIAL_TXX9 #include <linux/tty.h> #include <linux/serial.h> #include <linux/serial_core.h> #endif +#include <linux/spi/spi.h> +#include <asm/tx4938/spi.h> +#include <asm/gpio.h> extern void rbtx4938_time_init(void) __init; extern char * __init prom_getcmdline(void); @@ -575,44 +577,33 @@ arch_initcall(tx4938_pcibios_init); #define SEEPROM3_CS 1 /* IOC */ #define SRTC_CS 2 /* IOC */ -static int rbtx4938_spi_cs_func(int chipid, int on) +#ifdef CONFIG_PCI +static unsigned char rbtx4938_ethaddr[17]; +static int __init rbtx4938_ethaddr_init(void) { - unsigned char bit; - switch (chipid) { - case RBTX4938_SEEPROM1_CHIPID: - if (on) - tx4938_pioptr->dout &= ~(1 << SEEPROM1_CS); - else - tx4938_pioptr->dout |= (1 << SEEPROM1_CS); - return 0; - break; - case RBTX4938_SEEPROM2_CHIPID: - bit = (1 << SEEPROM2_CS); - break; - case RBTX4938_SEEPROM3_CHIPID: - bit = (1 << SEEPROM3_CS); - break; - case RBTX4938_SRTC_CHIPID: - bit = (1 << SRTC_CS); - break; - default: - return -ENODEV; + unsigned char sum; + int i; + + /* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */ + if (spi_eeprom_read(SEEPROM1_CS, 0, + rbtx4938_ethaddr, sizeof(rbtx4938_ethaddr))) + printk(KERN_ERR "seeprom: read error.\n"); + else { + unsigned char *dat = rbtx4938_ethaddr; + if (strcmp(dat, "MAC") != 0) + printk(KERN_WARNING "seeprom: bad signature.\n"); + for (i = 0, sum = 0; i < sizeof(dat); i++) + sum += dat[i]; + if (sum) + printk(KERN_WARNING "seeprom: bad checksum.\n"); } - /* bit1,2,4 are low active, bit3 is high active */ - *rbtx4938_spics_ptr = - (*rbtx4938_spics_ptr & ~bit) | - ((on ? (bit ^ 0x0b) : ~(bit ^ 0x0b)) & bit); return 0; } - -#ifdef CONFIG_PCI -extern int spi_eeprom_read(int chipid, int address, unsigned char *buf, int len); +device_initcall(rbtx4938_ethaddr_init); int rbtx4938_get_tx4938_ethaddr(struct pci_dev *dev, unsigned char *addr) { struct pci_controller *channel = (struct pci_controller *)dev->bus->sysdata; - static unsigned char dat[17]; - static int read_dat = 0; int ch = 0; if (channel != &tx4938_pci_controller[1]) @@ -628,29 +619,11 @@ int rbtx4938_get_tx4938_ethaddr(struct pci_dev *dev, unsigned char *addr) default: return -ENODEV; } - if (!read_dat) { - unsigned char sum; - int i; - read_dat = 1; - /* 0-3: "MAC\0", 4-9:eth0, 10-15:eth1, 16:sum */ - if (spi_eeprom_read(RBTX4938_SEEPROM1_CHIPID, - 0, dat, sizeof(dat))) { - printk(KERN_ERR "seeprom: read error.\n"); - } else { - if (strcmp(dat, "MAC") != 0) - printk(KERN_WARNING "seeprom: bad signature.\n"); - for (i = 0, sum = 0; i < sizeof(dat); i++) - sum += dat[i]; - if (sum) - printk(KERN_WARNING "seeprom: bad checksum.\n"); - } - } - memcpy(addr, &dat[4 + 6 * ch], 6); + memcpy(addr, &rbtx4938_ethaddr[4 + 6 * ch], 6); return 0; } #endif /* CONFIG_PCI */ -extern void __init txx9_spi_init(unsigned long base, int (*cs_func)(int chipid, int on)); static void __init rbtx4938_spi_setup(void) { /* set SPI_SEL */ @@ -658,7 +631,6 @@ static void __init rbtx4938_spi_setup(void) /* chip selects for SPI devices */ tx4938_pioptr->dout |= (1 << SEEPROM1_CS); tx4938_pioptr->dir |= (1 << SEEPROM1_CS); - txx9_spi_init(TX4938_SPI_REG, rbtx4938_spi_cs_func); } static struct resource rbtx4938_fpga_resource; @@ -897,10 +869,8 @@ void tx4938_report_pcic_status(void) /* We use onchip r4k counter or TMR timer as our system wide timer * interrupt running at 100HZ. */ -extern void __init rtc_rx5c348_init(int chipid); void __init rbtx4938_time_init(void) { - rtc_rx5c348_init(RBTX4938_SRTC_CHIPID); mips_hpt_frequency = txx9_cpu_clock / 2; } @@ -1017,29 +987,6 @@ void __init toshiba_rbtx4938_setup(void) *rbtx4938_dipsw_ptr, *rbtx4938_bdipsw_ptr); } -#ifdef CONFIG_PROC_FS -extern void spi_eeprom_proc_create(struct proc_dir_entry *dir, int chipid); -static int __init tx4938_spi_proc_setup(void) -{ - struct proc_dir_entry *tx4938_spi_eeprom_dir; - - tx4938_spi_eeprom_dir = proc_mkdir("spi_eeprom", 0); - - if (!tx4938_spi_eeprom_dir) - return -ENOMEM; - - /* don't allow user access to RBTX4938_SEEPROM1_CHIPID - * as it contains eth0 and eth1 MAC addresses - */ - spi_eeprom_proc_create(tx4938_spi_eeprom_dir, RBTX4938_SEEPROM2_CHIPID); - spi_eeprom_proc_create(tx4938_spi_eeprom_dir, RBTX4938_SEEPROM3_CHIPID); - - return 0; -} - -__initcall(tx4938_spi_proc_setup); -#endif - static int __init rbtx4938_ne_init(void) { struct resource res[] = { @@ -1161,3 +1108,73 @@ void gpio_set_value(unsigned gpio, int value) else rbtx4938_spi_gpio_set(gpio, value); } + +/* SPI support */ + +static void __init txx9_spi_init(unsigned long base, int irq) +{ + struct resource res[] = { + { + .start = base, + .end = base + 0x20 - 1, + .flags = IORESOURCE_MEM, + .parent = &tx4938_reg_resource, + }, { + .start = irq, + .flags = IORESOURCE_IRQ, + }, + }; + platform_device_register_simple("txx9spi", 0, + res, ARRAY_SIZE(res)); +} + +static int __init rbtx4938_spi_init(void) +{ + struct spi_board_info srtc_info = { + .modalias = "rs5c348", + .max_speed_hz = 1000000, /* 1.0Mbps @ Vdd 2.0V */ + .bus_num = 0, + .chip_select = 16 + SRTC_CS, + /* Mode 1 (High-Active, Shift-Then-Sample), High Avtive CS */ + .mode = SPI_MODE_1 | SPI_CS_HIGH, + }; + spi_register_board_info(&srtc_info, 1); + spi_eeprom_register(SEEPROM1_CS); + spi_eeprom_register(16 + SEEPROM2_CS); + spi_eeprom_register(16 + SEEPROM3_CS); + txx9_spi_init(TX4938_SPI_REG & 0xfffffffffULL, RBTX4938_IRQ_IRC_SPI); + return 0; +} +arch_initcall(rbtx4938_spi_init); + +/* Minimum CLK support */ + +struct clk *clk_get(struct device *dev, const char *id) +{ + if (!strcmp(id, "spi-baseclk")) + return (struct clk *)(txx9_gbus_clock / 2 / 4); + return ERR_PTR(-ENOENT); +} +EXPORT_SYMBOL(clk_get); + +int clk_enable(struct clk *clk) +{ + return 0; +} +EXPORT_SYMBOL(clk_enable); + +void clk_disable(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_disable); + +unsigned long clk_get_rate(struct clk *clk) +{ + return (unsigned long)clk; +} +EXPORT_SYMBOL(clk_get_rate); + +void clk_put(struct clk *clk) +{ +} +EXPORT_SYMBOL(clk_put); |