aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/net/phy/dp83640.c
diff options
context:
space:
mode:
authorRichard Cochran <richardcochran@gmail.com>2014-03-20 17:21:58 -0400
committerDavid S. Miller <davem@davemloft.net>2014-03-21 14:21:15 -0400
commit86dd3612e1e0ffdfafa15021581bb45419d479b9 (patch)
treee6349ce0a6bcba5328a20b470713abb690a98a55 /drivers/net/phy/dp83640.c
parent564ca56e45469f48703b1de72ac64d143d18d0ee (diff)
dp83640: implement programmable pin functions.
This patch adapts the dp83640 driver to allow reconfiguration of which auxiliary function goes on which pin. The functions may be reassigned freely with the one exception of the calibration function. Signed-off-by: Richard Cochran <richardcochran@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'drivers/net/phy/dp83640.c')
-rw-r--r--drivers/net/phy/dp83640.c52
1 files changed, 52 insertions, 0 deletions
diff --git a/drivers/net/phy/dp83640.c b/drivers/net/phy/dp83640.c
index 9e265553e8e4..43b583b2bed7 100644
--- a/drivers/net/phy/dp83640.c
+++ b/drivers/net/phy/dp83640.c
@@ -47,6 +47,7 @@
47#define CAL_EVENT 7 47#define CAL_EVENT 7
48#define CAL_TRIGGER 7 48#define CAL_TRIGGER 7
49#define PER_TRIGGER 6 49#define PER_TRIGGER 6
50#define DP83640_N_PINS 12
50 51
51#define MII_DP83640_MICR 0x11 52#define MII_DP83640_MICR 0x11
52#define MII_DP83640_MISR 0x12 53#define MII_DP83640_MISR 0x12
@@ -173,6 +174,37 @@ MODULE_PARM_DESC(chosen_phy, \
173MODULE_PARM_DESC(gpio_tab, \ 174MODULE_PARM_DESC(gpio_tab, \
174 "Which GPIO line to use for which purpose: cal,perout,extts1,...,extts6"); 175 "Which GPIO line to use for which purpose: cal,perout,extts1,...,extts6");
175 176
177static void dp83640_gpio_defaults(struct ptp_pin_desc *pd)
178{
179 int i, index;
180
181 for (i = 0; i < DP83640_N_PINS; i++) {
182 snprintf(pd[i].name, sizeof(pd[i].name), "GPIO%d", 1 + i);
183 pd[i].index = i;
184 }
185
186 for (i = 0; i < GPIO_TABLE_SIZE; i++) {
187 if (gpio_tab[i] < 1 || gpio_tab[i] > DP83640_N_PINS) {
188 pr_err("gpio_tab[%d]=%hu out of range", i, gpio_tab[i]);
189 return;
190 }
191 }
192
193 index = gpio_tab[CALIBRATE_GPIO] - 1;
194 pd[index].func = PTP_PF_PHYSYNC;
195 pd[index].chan = 0;
196
197 index = gpio_tab[PEROUT_GPIO] - 1;
198 pd[index].func = PTP_PF_PEROUT;
199 pd[index].chan = 0;
200
201 for (i = EXTTS0_GPIO; i < GPIO_TABLE_SIZE; i++) {
202 index = gpio_tab[i] - 1;
203 pd[index].func = PTP_PF_EXTTS;
204 pd[index].chan = i - EXTTS0_GPIO;
205 }
206}
207
176/* a list of clocks and a mutex to protect it */ 208/* a list of clocks and a mutex to protect it */
177static LIST_HEAD(phyter_clocks); 209static LIST_HEAD(phyter_clocks);
178static DEFINE_MUTEX(phyter_clocks_lock); 210static DEFINE_MUTEX(phyter_clocks_lock);
@@ -459,6 +491,12 @@ static int ptp_dp83640_enable(struct ptp_clock_info *ptp,
459 return -EOPNOTSUPP; 491 return -EOPNOTSUPP;
460} 492}
461 493
494static int ptp_dp83640_verify(struct ptp_clock_info *ptp, unsigned int pin,
495 enum ptp_pin_function func, unsigned int chan)
496{
497 return 0;
498}
499
462static u8 status_frame_dst[6] = { 0x01, 0x1B, 0x19, 0x00, 0x00, 0x00 }; 500static u8 status_frame_dst[6] = { 0x01, 0x1B, 0x19, 0x00, 0x00, 0x00 };
463static u8 status_frame_src[6] = { 0x08, 0x00, 0x17, 0x0B, 0x6B, 0x0F }; 501static u8 status_frame_src[6] = { 0x08, 0x00, 0x17, 0x0B, 0x6B, 0x0F };
464 502
@@ -876,6 +914,7 @@ static void dp83640_free_clocks(void)
876 mutex_destroy(&clock->extreg_lock); 914 mutex_destroy(&clock->extreg_lock);
877 mutex_destroy(&clock->clock_lock); 915 mutex_destroy(&clock->clock_lock);
878 put_device(&clock->bus->dev); 916 put_device(&clock->bus->dev);
917 kfree(clock->caps.pin_config);
879 kfree(clock); 918 kfree(clock);
880 } 919 }
881 920
@@ -895,12 +934,18 @@ static void dp83640_clock_init(struct dp83640_clock *clock, struct mii_bus *bus)
895 clock->caps.n_alarm = 0; 934 clock->caps.n_alarm = 0;
896 clock->caps.n_ext_ts = N_EXT_TS; 935 clock->caps.n_ext_ts = N_EXT_TS;
897 clock->caps.n_per_out = 1; 936 clock->caps.n_per_out = 1;
937 clock->caps.n_pins = DP83640_N_PINS;
898 clock->caps.pps = 0; 938 clock->caps.pps = 0;
899 clock->caps.adjfreq = ptp_dp83640_adjfreq; 939 clock->caps.adjfreq = ptp_dp83640_adjfreq;
900 clock->caps.adjtime = ptp_dp83640_adjtime; 940 clock->caps.adjtime = ptp_dp83640_adjtime;
901 clock->caps.gettime = ptp_dp83640_gettime; 941 clock->caps.gettime = ptp_dp83640_gettime;
902 clock->caps.settime = ptp_dp83640_settime; 942 clock->caps.settime = ptp_dp83640_settime;
903 clock->caps.enable = ptp_dp83640_enable; 943 clock->caps.enable = ptp_dp83640_enable;
944 clock->caps.verify = ptp_dp83640_verify;
945 /*
946 * Convert the module param defaults into a dynamic pin configuration.
947 */
948 dp83640_gpio_defaults(clock->caps.pin_config);
904 /* 949 /*
905 * Get a reference to this bus instance. 950 * Get a reference to this bus instance.
906 */ 951 */
@@ -951,6 +996,13 @@ static struct dp83640_clock *dp83640_clock_get_bus(struct mii_bus *bus)
951 if (!clock) 996 if (!clock)
952 goto out; 997 goto out;
953 998
999 clock->caps.pin_config = kzalloc(sizeof(struct ptp_pin_desc) *
1000 DP83640_N_PINS, GFP_KERNEL);
1001 if (!clock->caps.pin_config) {
1002 kfree(clock);
1003 clock = NULL;
1004 goto out;
1005 }
954 dp83640_clock_init(clock, bus); 1006 dp83640_clock_init(clock, bus);
955 list_add_tail(&phyter_clocks, &clock->list); 1007 list_add_tail(&phyter_clocks, &clock->list);
956out: 1008out: