#include <linux/can/dev.h>
#include <linux/can/error.h>
#include <linux/can/led.h>
-#include <linux/can/platform/flexcan.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/if_arp.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/platform_device.h>
+#include <linux/regulator/consumer.h>
#define DRV_NAME "flexcan"
struct clk *clk_per;
struct flexcan_platform_data *pdata;
const struct flexcan_devtype_data *devtype_data;
+ struct regulator *reg_xceiver;
};
static struct flexcan_devtype_data fsl_p1010_devtype_data = {
}
#endif
-/*
- * Swtich transceiver on or off
- */
-static void flexcan_transceiver_switch(const struct flexcan_priv *priv, int on)
-{
- if (priv->pdata && priv->pdata->transceiver_switch)
- priv->pdata->transceiver_switch(on);
-}
-
static inline int flexcan_has_and_handle_berr(const struct flexcan_priv *priv,
u32 reg_esr)
{
if (priv->devtype_data->features & FLEXCAN_HAS_V10_FEATURES)
flexcan_write(0x0, ®s->rxfgmask);
- flexcan_transceiver_switch(priv, 1);
+ if (priv->reg_xceiver) {
+ err = regulator_enable(priv->reg_xceiver);
+ if (err)
+ goto out;
+ }
/* synchronize with the can bus */
reg_mcr = flexcan_read(®s->mcr);
reg |= FLEXCAN_MCR_MDIS | FLEXCAN_MCR_HALT;
flexcan_write(reg, ®s->mcr);
- flexcan_transceiver_switch(priv, 0);
+ if (priv->reg_xceiver)
+ regulator_disable(priv->reg_xceiver);
priv->can.state = CAN_STATE_STOPPED;
return;
priv->pdata = pdev->dev.platform_data;
priv->devtype_data = devtype_data;
+ priv->reg_xceiver = devm_regulator_get(&pdev->dev, "xceiver");
+ if (IS_ERR(priv->reg_xceiver))
+ priv->reg_xceiver = NULL;
+
netif_napi_add(dev, &priv->napi, flexcan_poll, FLEXCAN_NAPI_WEIGHT);
dev_set_drvdata(&pdev->dev, dev);