diff options
Diffstat (limited to 'drivers/fsi/fsi-core.c')
-rw-r--r-- | drivers/fsi/fsi-core.c | 31 |
1 files changed, 28 insertions, 3 deletions
diff --git a/drivers/fsi/fsi-core.c b/drivers/fsi/fsi-core.c index 8244da8a7241..4e60e84cd17a 100644 --- a/drivers/fsi/fsi-core.c +++ b/drivers/fsi/fsi-core.c @@ -50,6 +50,7 @@ static const int engine_page_size = 0x400; #define FSI_SMODE 0x0 /* R/W: Mode register */ #define FSI_SISC 0x8 /* R/W: Interrupt condition */ #define FSI_SSTAT 0x14 /* R : Slave status */ +#define FSI_SLBUS 0x30 /* W : LBUS Ownership */ #define FSI_LLMODE 0x100 /* R/W: Link layer mode register */ /* @@ -67,6 +68,11 @@ static const int engine_page_size = 0x400; #define FSI_SMODE_LBCRR_MASK 0xf /* Clk ratio mask */ /* + * SLBUS fields + */ +#define FSI_SLBUS_FORCE 0x80000000 /* Force LBUS ownership */ + +/* * LLMODE fields */ #define FSI_LLMODE_ASYNC 0x1 @@ -981,7 +987,7 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id) uint32_t cfam_id; struct fsi_slave *slave; uint8_t crc; - __be32 data, llmode; + __be32 data, llmode, slbus; int rc; /* Currently, we only support single slaves on a link, and use the @@ -1052,6 +1058,14 @@ static int fsi_slave_init(struct fsi_master *master, int link, uint8_t id) } + slbus = cpu_to_be32(FSI_SLBUS_FORCE); + rc = fsi_master_write(master, link, id, FSI_SLAVE_BASE + FSI_SLBUS, + &slbus, sizeof(slbus)); + if (rc) + dev_warn(&master->dev, + "can't set slbus on slave:%02x:%02x %d\n", link, id, + rc); + rc = fsi_slave_set_smode(slave); if (rc) { dev_warn(&master->dev, @@ -1154,10 +1168,18 @@ static int fsi_master_write(struct fsi_master *master, int link, return rc; } +static int fsi_master_link_disable(struct fsi_master *master, int link) +{ + if (master->link_enable) + return master->link_enable(master, link, false); + + return 0; +} + static int fsi_master_link_enable(struct fsi_master *master, int link) { if (master->link_enable) - return master->link_enable(master, link); + return master->link_enable(master, link, true); return 0; } @@ -1192,12 +1214,15 @@ static int fsi_master_scan(struct fsi_master *master) } rc = fsi_master_break(master, link); if (rc) { + fsi_master_link_disable(master, link); dev_dbg(&master->dev, "break to link %d failed: %d\n", link, rc); continue; } - fsi_slave_init(master, link, 0); + rc = fsi_slave_init(master, link, 0); + if (rc) + fsi_master_link_disable(master, link); } return 0; |