diff options
-rwxr-xr-x | arch/arm/mach-tegra/include/nvrm_owr.h | 9 | ||||
-rwxr-xr-x | arch/arm/mach-tegra/nvrm/io/ap20/ap20rm_owr.c | 85 | ||||
-rwxr-xr-x | arch/arm/mach-tegra/nvrm/io/common/nvrm_owr.c | 3 | ||||
-rw-r--r-- | drivers/w1/masters/tegra_w1.c | 67 |
4 files changed, 163 insertions, 1 deletions
diff --git a/arch/arm/mach-tegra/include/nvrm_owr.h b/arch/arm/mach-tegra/include/nvrm_owr.h index c8af6f79c7a7..8aebb28e4ad0 100755 --- a/arch/arm/mach-tegra/include/nvrm_owr.h +++ b/arch/arm/mach-tegra/include/nvrm_owr.h @@ -108,6 +108,15 @@ typedef enum /// OWR memory Check Presence NvRmOwr_CheckPresence, + + /// OWR readbit transaction. + /// The LSB will be received first. + NvRmOwr_ReadBit, + + /// OWR writebit transaction. + /// The LSB will be transmitted first. + NvRmOwr_WriteBit, + NvRmOwrTransactionFlags_Num, NvRmOwrTransactionFlags_Force32 = 0x7FFFFFFF } NvRmOwrTransactionFlags; diff --git a/arch/arm/mach-tegra/nvrm/io/ap20/ap20rm_owr.c b/arch/arm/mach-tegra/nvrm/io/ap20/ap20rm_owr.c index ee8a45d55811..17f0251003bf 100755 --- a/arch/arm/mach-tegra/nvrm/io/ap20/ap20rm_owr.c +++ b/arch/arm/mach-tegra/nvrm/io/ap20/ap20rm_owr.c @@ -116,6 +116,7 @@ void PrivOwrEnableInterrupts(NvRmOwrController *pOwrInfo, NvU32 OwrIntStatus); NvError PrivOwrSendCommand(NvRmOwrController *pOwrInfo, NvU32 Command); +NvError PrivOwrSendBit(NvRmOwrController *pOwrInfo, NvU32 Bit); NvError PrivOwrCheckBitTransferDone( @@ -128,6 +129,11 @@ PrivOwrReadData( NvU8* Buffer, NvU32 NoOfBytes); +NvError +PrivOwrReadDataBit( + NvRmOwrController *pOwrInfo, + NvU8* Buffer); + static NvError PrivOwrCheckPresence( NvRmOwrController* pOwrInfo, @@ -250,6 +256,40 @@ NvError PrivOwrSendCommand(NvRmOwrController *pOwrInfo, NvU32 Command) return NvSuccess; } +NvError PrivOwrSendBit(NvRmOwrController *pOwrInfo, NvU32 Bit) +{ + NvU32 val = 0; + NvU32 data = Bit; + NvError status = NvError_Timeout; + NvU32 ControlReg = 0; + + val = + (NV_DRF_NUM(OWR, CONTROL, RD_DATA_SAMPLE_CLK, 0x7) | + NV_DRF_NUM(OWR, CONTROL, PRESENCE_SAMPLE_CLK, 0x50) | + NV_DRF_DEF(OWR, CONTROL, DATA_TRANSFER_MODE, BIT_TRANSFER_MODE)); + + if (data & 0x1) + { + ControlReg = + val | (NV_DRF_DEF(OWR, CONTROL, WR1_BIT, TRANSFER_ONE)); + } + else + { + ControlReg = + val | (NV_DRF_DEF(OWR, CONTROL, WR0_BIT, TRANSFER_ZERO)); + } + OWR_REGW(pOwrInfo->pOwrVirtualAddress, CONTROL, ControlReg); + + status = PrivOwrCheckBitTransferDone(pOwrInfo, + OwrIntrStatus_BitTransferDoneIntEnable); + if (status != NvSuccess) + { + return status; + } + + return NvSuccess; +} + NvError PrivOwrReadData( NvRmOwrController *pOwrInfo, @@ -291,6 +331,34 @@ PrivOwrReadData( return NvSuccess; } +NvError +PrivOwrReadDataBit( + NvRmOwrController *pOwrInfo, + NvU8* Buffer) +{ + NvU32 ControlReg = 0; + NvError status = NvError_Timeout; + NvU32 val = 0; + + ControlReg = + NV_DRF_NUM(OWR, CONTROL, RD_DATA_SAMPLE_CLK, 0x7) | + NV_DRF_NUM(OWR, CONTROL, PRESENCE_SAMPLE_CLK, 0x50) | + NV_DRF_DEF(OWR, CONTROL, DATA_TRANSFER_MODE, BIT_TRANSFER_MODE) | + NV_DRF_DEF(OWR, CONTROL, RD_BIT, TRANSFER_READ_SLOT); + + OWR_REGW(pOwrInfo->pOwrVirtualAddress, CONTROL, ControlReg); + status = PrivOwrCheckBitTransferDone(pOwrInfo, + OwrIntrStatus_BitTransferDoneIntEnable); + if (status != NvSuccess) + { + return status; + } + val = OWR_REGR(pOwrInfo->pOwrVirtualAddress, STATUS); + val = NV_DRF_VAL(OWR, STATUS, READ_SAMPLED_BIT, val); + *Buffer = val; + return NvSuccess; +} + static NvError PrivOwrReadFifo( NvRmOwrController* pOwrInfo, @@ -644,6 +712,15 @@ AP20RmOwrRead( status = PrivOwrReadData(pOwrInfo, pReadPtr, 1); } + else if (Transaction.Flags == NvRmOwr_ReadBit) + { + NV_ASSERT(!IsByteModeSupported); + pOwrInfo->OwrTransferStatus = 0; + // Enable the bit transfer done interrupt + PrivOwrEnableInterrupts(pOwrInfo, + OwrIntrStatus_BitTransferDoneIntEnable); + status = PrivOwrReadDataBit(pOwrInfo, pReadPtr); + } else if ((Transaction.Flags == NvRmOwr_MemRead) || (Transaction.Flags == NvRmOwr_ReadAddress)) { @@ -844,6 +921,14 @@ AP20RmOwrWrite( pOwrInfo->OwrTransferStatus = 0; status = PrivOwrSendCommand(pOwrInfo, (NvU32)(*pWritePtr)); } + else if(Transaction.Flags == NvRmOwr_WriteBit) + { + // Enable the bit transfer done interrupt + PrivOwrEnableInterrupts(pOwrInfo, OwrIntrStatus_BitTransferDoneIntEnable); + pOwrInfo->OwrTransferStatus = 0; + status = PrivOwrSendBit(pOwrInfo, (NvU32)(*pWritePtr)); + } + return status; } diff --git a/arch/arm/mach-tegra/nvrm/io/common/nvrm_owr.c b/arch/arm/mach-tegra/nvrm/io/common/nvrm_owr.c index bb46054fde9e..6334f0722182 100755 --- a/arch/arm/mach-tegra/nvrm/io/common/nvrm_owr.c +++ b/arch/arm/mach-tegra/nvrm/io/common/nvrm_owr.c @@ -357,7 +357,8 @@ NvError NvRmOwrTransaction( for (i = 0; i < NumOfTransactions; i++) { if ((Transaction[i].Flags == NvRmOwr_MemWrite) || - (Transaction[i].Flags == NvRmOwr_WriteByte)) + (Transaction[i].Flags == NvRmOwr_WriteByte) || + (Transaction[i].Flags == NvRmOwr_WriteBit)) { // OWR write transaction status = (pOwrInfo->write)( diff --git a/drivers/w1/masters/tegra_w1.c b/drivers/w1/masters/tegra_w1.c index 4667180664c6..80050f6284b9 100644 --- a/drivers/w1/masters/tegra_w1.c +++ b/drivers/w1/masters/tegra_w1.c @@ -93,6 +93,70 @@ static void tegra_w1_write_byte(void *data, u8 a_byte) } } +static u8 tegra_w1_read_bit(void *data) +{ + struct tegra_w1_dev *dev = data; + NvRmOwrTransactionInfo tInfo; + NvError err; + u8 buffer[1]; + + tInfo.Flags = NvRmOwr_ReadBit; + tInfo.NumBytes = 1; + tInfo.Address = 0; + tInfo.Offset = 0; + + err = NvRmOwrTransaction(dev->OwrHandle, dev->pin_map, + buffer, tInfo.NumBytes, &tInfo, 1); + if (err != NvSuccess) + { + printk(KERN_ERR "tegra_w1_read_bit failed 0x%x\r\n", err); + err = -EIO; + } + + if (!err) + return (buffer[0] & 0x1); + else + return 0; +} + +static void tegra_w1_write_bit(void *data, u8 bit) +{ + struct tegra_w1_dev *dev = data; + NvRmOwrTransactionInfo tInfo; + NvError err; + u8 buffer[1]; + + tInfo.Flags = NvRmOwr_WriteBit; + tInfo.NumBytes = 1; + tInfo.Address = 0; + tInfo.Offset = 0; + buffer[0] = bit & 0x1; + + err = NvRmOwrTransaction(dev->OwrHandle, dev->pin_map, + buffer, tInfo.NumBytes, &tInfo, 1); + if (err != NvSuccess) + { + printk(KERN_ERR "tegra_w1_write_bit failed 0x%x\r\n", err); + err = -EIO; + } +} + +/* Performs a write-0 or write-1 cycle and samples the level */ +static u8 tegra_w1_touch_bit(void *data, u8 bit) +{ + struct tegra_w1_dev *dev = data; + + if (bit) + { + return tegra_w1_read_bit(dev); + } + else + { + tegra_w1_write_bit(dev, 0); + return 0; + } +} + static u8 tegra_w1_reset_bus(void *data) { struct tegra_w1_dev *dev = data; @@ -155,6 +219,9 @@ static int tegra_w1_probe(struct platform_device *pdev) dev->bus_master.data = dev; dev->bus_master.read_byte = tegra_w1_read_byte; dev->bus_master.write_byte = tegra_w1_write_byte; + dev->bus_master.read_bit = tegra_w1_read_bit; + dev->bus_master.write_bit = tegra_w1_write_bit; + dev->bus_master.touch_bit = tegra_w1_touch_bit; dev->bus_master.reset_bus = tegra_w1_reset_bus; if (tegra_w1_reset_bus(dev)) |