summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHoang Pham <hopham@nvidia.com>2010-02-25 14:35:57 -0800
committerHoang Pham <hopham@nvidia.com>2010-02-25 14:35:57 -0800
commit3c5f25f31edf3ae05052d69db18417d1908ac171 (patch)
treeff87cb7d6ba442692095b611dd1244d2394b67eb
parentb9976e304f288a37b3eb9894a89e9c49eb57ee1a (diff)
tegra-w1: Add support read_bit, write_bit and touch_bit routines
Change-Id: I313de2e32b1dd64470ce7eb9f21a60c590e689c6
-rwxr-xr-xarch/arm/mach-tegra/include/nvrm_owr.h9
-rwxr-xr-xarch/arm/mach-tegra/nvrm/io/ap20/ap20rm_owr.c85
-rwxr-xr-xarch/arm/mach-tegra/nvrm/io/common/nvrm_owr.c3
-rw-r--r--drivers/w1/masters/tegra_w1.c67
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))