2010-09-27 16:05:49 +00:00
/*
* linux / arch / arm / mach - omap2 / gpmc - smsc911x . c
*
* Copyright ( C ) 2009 Li - Pro . Net
* Stephan Linz < linz @ li - pro . net >
*
* Modified from linux / arch / arm / mach - omap2 / gpmc - smc91x . c
*
* This program is free software ; you can redistribute it and / or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation .
*/
2011-04-26 16:25:56 +00:00
# define pr_fmt(fmt) "%s: " fmt, __func__
2010-09-27 16:05:49 +00:00
# include <linux/kernel.h>
# include <linux/platform_device.h>
# include <linux/gpio.h>
# include <linux/delay.h>
# include <linux/interrupt.h>
# include <linux/io.h>
# include <linux/smsc911x.h>
# include <plat/board.h>
# include <plat/gpmc.h>
# include <plat/gpmc-smsc911x.h>
static struct omap_smsc911x_platform_data * gpmc_cfg ;
static struct resource gpmc_smsc911x_resources [ ] = {
[ 0 ] = {
. flags = IORESOURCE_MEM ,
} ,
[ 1 ] = {
2011-04-16 22:29:29 +00:00
. flags = IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL ,
2010-09-27 16:05:49 +00:00
} ,
} ;
static struct smsc911x_platform_config gpmc_smsc911x_config = {
. phy_interface = PHY_INTERFACE_MODE_MII ,
. irq_polarity = SMSC911X_IRQ_POLARITY_ACTIVE_LOW ,
. irq_type = SMSC911X_IRQ_TYPE_OPEN_DRAIN ,
. flags = SMSC911X_USE_16BIT ,
} ;
/*
* Initialize smsc911x device connected to the GPMC . Note that we
* assume that pin multiplexing is done in the board - * . c file ,
* or in the bootloader .
*/
void __init gpmc_smsc911x_init ( struct omap_smsc911x_platform_data * board_data )
{
2011-04-16 22:29:30 +00:00
struct platform_device * pdev ;
2010-09-27 16:05:49 +00:00
unsigned long cs_mem_base ;
int ret ;
gpmc_cfg = board_data ;
if ( gpmc_cs_request ( gpmc_cfg - > cs , SZ_16M , & cs_mem_base ) < 0 ) {
2011-04-26 16:25:56 +00:00
pr_err ( " Failed to request GPMC mem region \n " ) ;
2010-09-27 16:05:49 +00:00
return ;
}
gpmc_smsc911x_resources [ 0 ] . start = cs_mem_base + 0x0 ;
gpmc_smsc911x_resources [ 0 ] . end = cs_mem_base + 0xff ;
2011-05-03 18:22:09 +03:00
if ( gpio_request_one ( gpmc_cfg - > gpio_irq , GPIOF_IN , " smsc911x irq " ) ) {
2011-04-26 16:25:56 +00:00
pr_err ( " Failed to request IRQ GPIO%d \n " , gpmc_cfg - > gpio_irq ) ;
2010-09-27 16:05:49 +00:00
goto free1 ;
}
gpmc_smsc911x_resources [ 1 ] . start = gpio_to_irq ( gpmc_cfg - > gpio_irq ) ;
if ( gpio_is_valid ( gpmc_cfg - > gpio_reset ) ) {
2011-05-03 18:22:09 +03:00
ret = gpio_request_one ( gpmc_cfg - > gpio_reset ,
GPIOF_OUT_INIT_HIGH , " smsc911x reset " ) ;
2010-09-27 16:05:49 +00:00
if ( ret ) {
2011-04-26 16:25:56 +00:00
pr_err ( " Failed to request reset GPIO%d \n " ,
gpmc_cfg - > gpio_reset ) ;
2010-09-27 16:05:49 +00:00
goto free2 ;
}
gpio_set_value ( gpmc_cfg - > gpio_reset , 0 ) ;
msleep ( 100 ) ;
gpio_set_value ( gpmc_cfg - > gpio_reset , 1 ) ;
}
2011-04-16 22:29:29 +00:00
if ( gpmc_cfg - > flags )
gpmc_smsc911x_config . flags = gpmc_cfg - > flags ;
2011-04-16 22:29:30 +00:00
pdev = platform_device_register_resndata ( NULL , " smsc911x " , gpmc_cfg - > id ,
gpmc_smsc911x_resources , ARRAY_SIZE ( gpmc_smsc911x_resources ) ,
& gpmc_smsc911x_config , sizeof ( gpmc_smsc911x_config ) ) ;
if ( ! pdev ) {
2011-04-26 16:25:56 +00:00
pr_err ( " Unable to register platform device \n " ) ;
2010-09-27 16:05:49 +00:00
gpio_free ( gpmc_cfg - > gpio_reset ) ;
goto free2 ;
}
return ;
free2 :
gpio_free ( gpmc_cfg - > gpio_irq ) ;
free1 :
gpmc_cs_free ( gpmc_cfg - > cs ) ;
2011-04-26 16:25:56 +00:00
pr_err ( " Could not initialize smsc911x device \n " ) ;
2010-09-27 16:05:49 +00:00
}