| Tim Nordell | cdd280b | 2010-09-27 16:05:49 +0000 | [diff] [blame] | 1 | /* | 
 | 2 |  * linux/arch/arm/mach-omap2/gpmc-smsc911x.c | 
 | 3 |  * | 
 | 4 |  * Copyright (C) 2009 Li-Pro.Net | 
 | 5 |  * Stephan Linz <linz@li-pro.net> | 
 | 6 |  * | 
 | 7 |  * Modified from linux/arch/arm/mach-omap2/gpmc-smc91x.c | 
 | 8 |  * | 
 | 9 |  * This program is free software; you can redistribute it and/or modify | 
 | 10 |  * it under the terms of the GNU General Public License version 2 as | 
 | 11 |  * published by the Free Software Foundation. | 
 | 12 |  */ | 
| Igor Grinberg | 11383a9 | 2011-04-26 16:25:56 +0000 | [diff] [blame] | 13 | #define pr_fmt(fmt) "%s: " fmt, __func__ | 
| Tim Nordell | cdd280b | 2010-09-27 16:05:49 +0000 | [diff] [blame] | 14 |  | 
 | 15 | #include <linux/kernel.h> | 
 | 16 | #include <linux/platform_device.h> | 
 | 17 | #include <linux/gpio.h> | 
 | 18 | #include <linux/delay.h> | 
 | 19 | #include <linux/interrupt.h> | 
 | 20 | #include <linux/io.h> | 
 | 21 | #include <linux/smsc911x.h> | 
 | 22 |  | 
| Afzal Mohammed | 3ef5d00 | 2012-10-05 10:37:27 +0530 | [diff] [blame] | 23 | #include "gpmc.h" | 
| Tony Lindgren | ac839b3 | 2012-09-20 11:41:46 -0700 | [diff] [blame] | 24 | #include "gpmc-smsc911x.h" | 
| Tim Nordell | cdd280b | 2010-09-27 16:05:49 +0000 | [diff] [blame] | 25 |  | 
| Tim Nordell | cdd280b | 2010-09-27 16:05:49 +0000 | [diff] [blame] | 26 | static struct resource gpmc_smsc911x_resources[] = { | 
 | 27 | 	[0] = { | 
 | 28 | 		.flags		= IORESOURCE_MEM, | 
 | 29 | 	}, | 
 | 30 | 	[1] = { | 
| Mike Rapoport | f0949f7 | 2011-04-16 22:29:29 +0000 | [diff] [blame] | 31 | 		.flags		= IORESOURCE_IRQ | IORESOURCE_IRQ_LOWLEVEL, | 
| Tim Nordell | cdd280b | 2010-09-27 16:05:49 +0000 | [diff] [blame] | 32 | 	}, | 
 | 33 | }; | 
 | 34 |  | 
 | 35 | static struct smsc911x_platform_config gpmc_smsc911x_config = { | 
 | 36 | 	.phy_interface	= PHY_INTERFACE_MODE_MII, | 
 | 37 | 	.irq_polarity	= SMSC911X_IRQ_POLARITY_ACTIVE_LOW, | 
 | 38 | 	.irq_type	= SMSC911X_IRQ_TYPE_OPEN_DRAIN, | 
| Tim Nordell | cdd280b | 2010-09-27 16:05:49 +0000 | [diff] [blame] | 39 | }; | 
 | 40 |  | 
| Tim Nordell | cdd280b | 2010-09-27 16:05:49 +0000 | [diff] [blame] | 41 | /* | 
 | 42 |  * Initialize smsc911x device connected to the GPMC. Note that we | 
 | 43 |  * assume that pin multiplexing is done in the board-*.c file, | 
 | 44 |  * or in the bootloader. | 
 | 45 |  */ | 
| Russ Dill | 54da078 | 2012-03-23 02:21:33 -0700 | [diff] [blame] | 46 | void __init gpmc_smsc911x_init(struct omap_smsc911x_platform_data *gpmc_cfg) | 
| Tim Nordell | cdd280b | 2010-09-27 16:05:49 +0000 | [diff] [blame] | 47 | { | 
| Mike Rapoport | 21b4273 | 2011-04-16 22:29:30 +0000 | [diff] [blame] | 48 | 	struct platform_device *pdev; | 
| Tim Nordell | cdd280b | 2010-09-27 16:05:49 +0000 | [diff] [blame] | 49 | 	unsigned long cs_mem_base; | 
 | 50 | 	int ret; | 
 | 51 |  | 
| Tim Nordell | cdd280b | 2010-09-27 16:05:49 +0000 | [diff] [blame] | 52 | 	if (gpmc_cs_request(gpmc_cfg->cs, SZ_16M, &cs_mem_base) < 0) { | 
| Igor Grinberg | 11383a9 | 2011-04-26 16:25:56 +0000 | [diff] [blame] | 53 | 		pr_err("Failed to request GPMC mem region\n"); | 
| Tim Nordell | cdd280b | 2010-09-27 16:05:49 +0000 | [diff] [blame] | 54 | 		return; | 
 | 55 | 	} | 
 | 56 |  | 
 | 57 | 	gpmc_smsc911x_resources[0].start = cs_mem_base + 0x0; | 
 | 58 | 	gpmc_smsc911x_resources[0].end = cs_mem_base + 0xff; | 
 | 59 |  | 
| Igor Grinberg | bc593f5 | 2011-05-03 18:22:09 +0300 | [diff] [blame] | 60 | 	if (gpio_request_one(gpmc_cfg->gpio_irq, GPIOF_IN, "smsc911x irq")) { | 
| Igor Grinberg | 11383a9 | 2011-04-26 16:25:56 +0000 | [diff] [blame] | 61 | 		pr_err("Failed to request IRQ GPIO%d\n", gpmc_cfg->gpio_irq); | 
| Tim Nordell | cdd280b | 2010-09-27 16:05:49 +0000 | [diff] [blame] | 62 | 		goto free1; | 
 | 63 | 	} | 
 | 64 |  | 
| Tim Nordell | cdd280b | 2010-09-27 16:05:49 +0000 | [diff] [blame] | 65 | 	gpmc_smsc911x_resources[1].start = gpio_to_irq(gpmc_cfg->gpio_irq); | 
| Tim Nordell | cdd280b | 2010-09-27 16:05:49 +0000 | [diff] [blame] | 66 |  | 
 | 67 | 	if (gpio_is_valid(gpmc_cfg->gpio_reset)) { | 
| Igor Grinberg | bc593f5 | 2011-05-03 18:22:09 +0300 | [diff] [blame] | 68 | 		ret = gpio_request_one(gpmc_cfg->gpio_reset, | 
 | 69 | 				       GPIOF_OUT_INIT_HIGH, "smsc911x reset"); | 
| Tim Nordell | cdd280b | 2010-09-27 16:05:49 +0000 | [diff] [blame] | 70 | 		if (ret) { | 
| Igor Grinberg | 11383a9 | 2011-04-26 16:25:56 +0000 | [diff] [blame] | 71 | 			pr_err("Failed to request reset GPIO%d\n", | 
 | 72 | 			       gpmc_cfg->gpio_reset); | 
| Tim Nordell | cdd280b | 2010-09-27 16:05:49 +0000 | [diff] [blame] | 73 | 			goto free2; | 
 | 74 | 		} | 
 | 75 |  | 
| Tim Nordell | cdd280b | 2010-09-27 16:05:49 +0000 | [diff] [blame] | 76 | 		gpio_set_value(gpmc_cfg->gpio_reset, 0); | 
 | 77 | 		msleep(100); | 
 | 78 | 		gpio_set_value(gpmc_cfg->gpio_reset, 1); | 
 | 79 | 	} | 
 | 80 |  | 
| Russ Dill | a0dbf2a | 2012-03-23 02:21:34 -0700 | [diff] [blame] | 81 | 	gpmc_smsc911x_config.flags = gpmc_cfg->flags ? : SMSC911X_USE_16BIT; | 
| Mike Rapoport | f0949f7 | 2011-04-16 22:29:29 +0000 | [diff] [blame] | 82 |  | 
| Mike Rapoport | 21b4273 | 2011-04-16 22:29:30 +0000 | [diff] [blame] | 83 | 	pdev = platform_device_register_resndata(NULL, "smsc911x", gpmc_cfg->id, | 
 | 84 | 		 gpmc_smsc911x_resources, ARRAY_SIZE(gpmc_smsc911x_resources), | 
 | 85 | 		 &gpmc_smsc911x_config, sizeof(gpmc_smsc911x_config)); | 
 | 86 | 	if (!pdev) { | 
| Igor Grinberg | 11383a9 | 2011-04-26 16:25:56 +0000 | [diff] [blame] | 87 | 		pr_err("Unable to register platform device\n"); | 
| Tim Nordell | cdd280b | 2010-09-27 16:05:49 +0000 | [diff] [blame] | 88 | 		gpio_free(gpmc_cfg->gpio_reset); | 
 | 89 | 		goto free2; | 
 | 90 | 	} | 
 | 91 |  | 
 | 92 | 	return; | 
 | 93 |  | 
 | 94 | free2: | 
 | 95 | 	gpio_free(gpmc_cfg->gpio_irq); | 
 | 96 | free1: | 
 | 97 | 	gpmc_cs_free(gpmc_cfg->cs); | 
 | 98 |  | 
| Igor Grinberg | 11383a9 | 2011-04-26 16:25:56 +0000 | [diff] [blame] | 99 | 	pr_err("Could not initialize smsc911x device\n"); | 
| Tim Nordell | cdd280b | 2010-09-27 16:05:49 +0000 | [diff] [blame] | 100 | } |