diff options
author | Sriramakrishnan <srk@ti.com> | 2010-02-26 08:22:03 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2010-02-26 08:22:03 -0500 |
commit | 773c3e75d1fc7ea5058bfeab5d82bac5b85f8cd8 (patch) | |
tree | c72b423271c5d02956e2536ae7dad0ff94b62fab | |
parent | 738b0343e73604750feb107e063c28b3ca36cb84 (diff) |
can: ti hecc module : add platform specific initialization callback.
CAN module on AM3517 requires programming of IO expander as part
of init sequence - to enable CAN PHY. Added platform specific
callback to handle phy control(switch on /off).
Signed-off-by: Sriramakrishnan <srk@ti.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r-- | drivers/net/can/ti_hecc.c | 17 | ||||
-rw-r--r-- | include/linux/can/platform/ti_hecc.h | 8 |
2 files changed, 22 insertions, 3 deletions
diff --git a/drivers/net/can/ti_hecc.c b/drivers/net/can/ti_hecc.c index b861cd561074..0c3d2ba0d178 100644 --- a/drivers/net/can/ti_hecc.c +++ b/drivers/net/can/ti_hecc.c | |||
@@ -28,9 +28,11 @@ | |||
28 | * .mbx_offset = 0x2000, | 28 | * .mbx_offset = 0x2000, |
29 | * .int_line = 0, | 29 | * .int_line = 0, |
30 | * .revision = 1, | 30 | * .revision = 1, |
31 | * .transceiver_switch = hecc_phy_control, | ||
31 | * }; | 32 | * }; |
32 | * | 33 | * |
33 | * Please see include/can/platform/ti_hecc.h for description of above fields | 34 | * Please see include/linux/can/platform/ti_hecc.h for description of |
35 | * above fields. | ||
34 | * | 36 | * |
35 | */ | 37 | */ |
36 | 38 | ||
@@ -220,6 +222,7 @@ struct ti_hecc_priv { | |||
220 | u32 tx_head; | 222 | u32 tx_head; |
221 | u32 tx_tail; | 223 | u32 tx_tail; |
222 | u32 rx_next; | 224 | u32 rx_next; |
225 | void (*transceiver_switch)(int); | ||
223 | }; | 226 | }; |
224 | 227 | ||
225 | static inline int get_tx_head_mb(struct ti_hecc_priv *priv) | 228 | static inline int get_tx_head_mb(struct ti_hecc_priv *priv) |
@@ -317,6 +320,13 @@ static int ti_hecc_set_btc(struct ti_hecc_priv *priv) | |||
317 | return 0; | 320 | return 0; |
318 | } | 321 | } |
319 | 322 | ||
323 | static void ti_hecc_transceiver_switch(const struct ti_hecc_priv *priv, | ||
324 | int on) | ||
325 | { | ||
326 | if (priv->transceiver_switch) | ||
327 | priv->transceiver_switch(on); | ||
328 | } | ||
329 | |||
320 | static void ti_hecc_reset(struct net_device *ndev) | 330 | static void ti_hecc_reset(struct net_device *ndev) |
321 | { | 331 | { |
322 | u32 cnt; | 332 | u32 cnt; |
@@ -818,10 +828,13 @@ static int ti_hecc_open(struct net_device *ndev) | |||
818 | return err; | 828 | return err; |
819 | } | 829 | } |
820 | 830 | ||
831 | ti_hecc_transceiver_switch(priv, 1); | ||
832 | |||
821 | /* Open common can device */ | 833 | /* Open common can device */ |
822 | err = open_candev(ndev); | 834 | err = open_candev(ndev); |
823 | if (err) { | 835 | if (err) { |
824 | dev_err(ndev->dev.parent, "open_candev() failed %d\n", err); | 836 | dev_err(ndev->dev.parent, "open_candev() failed %d\n", err); |
837 | ti_hecc_transceiver_switch(priv, 0); | ||
825 | free_irq(ndev->irq, ndev); | 838 | free_irq(ndev->irq, ndev); |
826 | return err; | 839 | return err; |
827 | } | 840 | } |
@@ -842,6 +855,7 @@ static int ti_hecc_close(struct net_device *ndev) | |||
842 | ti_hecc_stop(ndev); | 855 | ti_hecc_stop(ndev); |
843 | free_irq(ndev->irq, ndev); | 856 | free_irq(ndev->irq, ndev); |
844 | close_candev(ndev); | 857 | close_candev(ndev); |
858 | ti_hecc_transceiver_switch(priv, 0); | ||
845 | 859 | ||
846 | return 0; | 860 | return 0; |
847 | } | 861 | } |
@@ -903,6 +917,7 @@ static int ti_hecc_probe(struct platform_device *pdev) | |||
903 | priv->hecc_ram_offset = pdata->hecc_ram_offset; | 917 | priv->hecc_ram_offset = pdata->hecc_ram_offset; |
904 | priv->mbx_offset = pdata->mbx_offset; | 918 | priv->mbx_offset = pdata->mbx_offset; |
905 | priv->int_line = pdata->int_line; | 919 | priv->int_line = pdata->int_line; |
920 | priv->transceiver_switch = pdata->transceiver_switch; | ||
906 | 921 | ||
907 | priv->can.bittiming_const = &ti_hecc_bittiming_const; | 922 | priv->can.bittiming_const = &ti_hecc_bittiming_const; |
908 | priv->can.do_set_mode = ti_hecc_do_set_mode; | 923 | priv->can.do_set_mode = ti_hecc_do_set_mode; |
diff --git a/include/linux/can/platform/ti_hecc.h b/include/linux/can/platform/ti_hecc.h index 4688c7bb1bd1..af17cb3f7a84 100644 --- a/include/linux/can/platform/ti_hecc.h +++ b/include/linux/can/platform/ti_hecc.h | |||
@@ -1,3 +1,6 @@ | |||
1 | #ifndef __CAN_PLATFORM_TI_HECC_H__ | ||
2 | #define __CAN_PLATFORM_TI_HECC_H__ | ||
3 | |||
1 | /* | 4 | /* |
2 | * TI HECC (High End CAN Controller) driver platform header | 5 | * TI HECC (High End CAN Controller) driver platform header |
3 | * | 6 | * |
@@ -23,6 +26,7 @@ | |||
23 | * @mbx_offset: Mailbox RAM offset | 26 | * @mbx_offset: Mailbox RAM offset |
24 | * @int_line: Interrupt line to use - 0 or 1 | 27 | * @int_line: Interrupt line to use - 0 or 1 |
25 | * @version: version for future use | 28 | * @version: version for future use |
29 | * @transceiver_switch: platform specific callback fn for transceiver control | ||
26 | * | 30 | * |
27 | * Platform data structure to get all platform specific settings. | 31 | * Platform data structure to get all platform specific settings. |
28 | * this structure also accounts the fact that the IP may have different | 32 | * this structure also accounts the fact that the IP may have different |
@@ -35,6 +39,6 @@ struct ti_hecc_platform_data { | |||
35 | u32 mbx_offset; | 39 | u32 mbx_offset; |
36 | u32 int_line; | 40 | u32 int_line; |
37 | u32 version; | 41 | u32 version; |
42 | void (*transceiver_switch) (int); | ||
38 | }; | 43 | }; |
39 | 44 | #endif | |
40 | |||