1/* 2 * spi_eeprom.c 3 * Copyright (C) 2000-2001 Toshiba Corporation 4 * 5 * 2003-2005 (c) MontaVista Software, Inc. This file is licensed under the 6 * terms of the GNU General Public License version 2. This program is 7 * licensed "as is" without any warranty of any kind, whether express 8 * or implied. 9 * 10 * Support for TX4938 in 2.6 - Manish Lachwani (mlachwani@mvista.com) 11 */ 12#include <linux/init.h> 13#include <linux/slab.h> 14#include <linux/export.h> 15#include <linux/device.h> 16#include <linux/spi/spi.h> 17#include <linux/spi/eeprom.h> 18#include <asm/txx9/spi.h> 19 20#define AT250X0_PAGE_SIZE 8 21 22/* register board information for at25 driver */ 23int __init spi_eeprom_register(int busid, int chipid, int size) 24{ 25 struct spi_board_info info = { 26 .modalias = "at25", 27 .max_speed_hz = 1500000, /* 1.5Mbps */ 28 .bus_num = busid, 29 .chip_select = chipid, 30 /* Mode 0: High-Active, Sample-Then-Shift */ 31 }; 32 struct spi_eeprom *eeprom; 33 eeprom = kzalloc(sizeof(*eeprom), GFP_KERNEL); 34 if (!eeprom) 35 return -ENOMEM; 36 strcpy(eeprom->name, "at250x0"); 37 eeprom->byte_len = size; 38 eeprom->page_size = AT250X0_PAGE_SIZE; 39 eeprom->flags = EE_ADDR1; 40 info.platform_data = eeprom; 41 return spi_register_board_info(&info, 1); 42} 43 44/* simple temporary spi driver to provide early access to seeprom. */ 45 46static struct read_param { 47 int busid; 48 int chipid; 49 int address; 50 unsigned char *buf; 51 int len; 52} *read_param; 53 54static int __init early_seeprom_probe(struct spi_device *spi) 55{ 56 int stat = 0; 57 u8 cmd[2]; 58 int len = read_param->len; 59 char *buf = read_param->buf; 60 int address = read_param->address; 61 62 dev_info(&spi->dev, "spiclk %u KHz.\n", 63 (spi->max_speed_hz + 500) / 1000); 64 if (read_param->busid != spi->master->bus_num || 65 read_param->chipid != spi->chip_select) 66 return -ENODEV; 67 while (len > 0) { 68 /* spi_write_then_read can only work with small chunk */ 69 int c = len < AT250X0_PAGE_SIZE ? len : AT250X0_PAGE_SIZE; 70 cmd[0] = 0x03; /* AT25_READ */ 71 cmd[1] = address; 72 stat = spi_write_then_read(spi, cmd, sizeof(cmd), buf, c); 73 buf += c; 74 len -= c; 75 address += c; 76 } 77 return stat; 78} 79 80static struct spi_driver early_seeprom_driver __initdata = { 81 .driver = { 82 .name = "at25", 83 .owner = THIS_MODULE, 84 }, 85 .probe = early_seeprom_probe, 86}; 87 88int __init spi_eeprom_read(int busid, int chipid, int address, 89 unsigned char *buf, int len) 90{ 91 int ret; 92 struct read_param param = { 93 .busid = busid, 94 .chipid = chipid, 95 .address = address, 96 .buf = buf, 97 .len = len 98 }; 99 100 read_param = ¶m; 101 ret = spi_register_driver(&early_seeprom_driver); 102 if (!ret) 103 spi_unregister_driver(&early_seeprom_driver); 104 return ret; 105} 106