3 Copyright 1996,2002,2005 Gregory D. Hager, Alfred A. Rizzi, Noah J. Cowan,
4 Jason Lapenta, Scott Smedley
6 This file is part of the DT3155 Device Driver.
8 The DT3155 Device Driver is free software; you can redistribute it
9 and/or modify it under the terms of the GNU General Public License as
10 published by the Free Software Foundation; either version 2 of the
11 License, or (at your option) any later version.
13 The DT3155 Device Driver is distributed in the hope that it will be
14 useful, but WITHOUT ANY WARRANTY; without even the implied warranty
15 of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with the DT3155 Device Driver; if not, write to the Free
20 Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
26 Date Programmer Description of changes made
27 -------------------------------------------------------------------
28 10-Oct-2001 SS port to 2.4 kernel.
29 24-Jul-2002 SS GPL licence.
30 26-Jul-2002 SS Bug fix: timing logic was wrong.
31 08-Aug-2005 SS port to 2.6 kernel.
35 /* This file provides some basic register io routines. It is modified
36 from demo code provided by Data Translations. */
39 #include <asm/delay.h>
43 #include <sys/param.h>
49 #include "dt3155_io.h"
50 #include "dt3155_drv.h"
57 /****** local copies of board's 32 bit registers ******/
58 u_long even_dma_start_r; /* bit 0 should always be 0 */
59 u_long odd_dma_start_r; /* .. */
60 u_long even_dma_stride_r; /* bits 0&1 should always be 0 */
61 u_long odd_dma_stride_r; /* .. */
62 u_long even_pixel_fmt_r;
63 u_long odd_pixel_fmt_r;
65 FIFO_TRIGGER_R fifo_trigger_r;
66 XFER_MODE_R xfer_mode_r;
68 RETRY_WAIT_CNT_R retry_wait_cnt_r;
71 u_long even_fld_mask_r;
72 u_long odd_fld_mask_r;
74 MASK_LENGTH_R mask_length_r;
75 FIFO_FLAG_CNT_R fifo_flag_cnt_r;
76 IIC_CLK_DUR_R iic_clk_dur_r;
77 IIC_CSR1_R iic_csr1_r;
78 IIC_CSR2_R iic_csr2_r;
79 DMA_UPPER_LMT_R even_dma_upper_lmt_r;
80 DMA_UPPER_LMT_R odd_dma_upper_lmt_r;
84 /******** local copies of board's 8 bit I2C registers ******/
86 I2C_EVEN_CSR i2c_even_csr;
87 I2C_ODD_CSR i2c_odd_csr;
88 I2C_CONFIG i2c_config;
96 I2C_AD_CMD i2c_ad_cmd;
102 // return the time difference (in microseconds) b/w <a> & <b>.
103 long elapsed2 (const struct timeval *pStart, const struct timeval *pEnd)
105 long i = (pEnd->tv_sec - pStart->tv_sec) * 1000000;
106 i += pEnd->tv_usec - pStart->tv_usec;
110 /***********************************************************************
113 This function handles read/write timing and r/w timeout error
115 Returns TRUE if NEW_CYCLE clears
116 Returns FALSE if NEW_CYCLE doesn't clear in roughly 3 msecs,
119 ***********************************************************************/
120 int wait_ibsyclr(u8 * lpReg)
122 /* wait 100 microseconds */
126 /* __delay(loops_per_sec/10000); */
127 if (iic_csr2_r.fld.NEW_CYCLE )
128 { /* if NEW_CYCLE didn't clear */
130 dt3155_errno = DT_ERR_I2C_TIMEOUT;
134 return TRUE; /* no error */
136 struct timeval StartTime;
137 struct timeval EndTime;
139 const int to_3ms = 3000; /* time out of 3ms = 3000us */
141 gettimeofday( &StartTime, NULL );
143 /* get new iic_csr2 value: */
144 ReadMReg((lpReg + IIC_CSR2), iic_csr2_r.reg);
145 gettimeofday( &EndTime, NULL );
147 while ((elapsed2(&StartTime, &EndTime) < to_3ms) && iic_csr2_r.fld.NEW_CYCLE);
149 if (iic_csr2_r.fld.NEW_CYCLE )
150 { /* if NEW_CYCLE didn't clear */
151 printf("Timed out waiting for NEW_CYCLE to clear!");
155 return TRUE; /* no error */
159 /***********************************************************************
162 This function handles writing to 8-bit DT3155 registers
164 1st parameter is pointer to 32-bit register base address
165 2nd parameter is reg. index;
166 3rd is value to be written
168 Returns TRUE - Successful completion
169 FALSE - Timeout error - cycle did not complete!
170 ***********************************************************************/
171 int WriteI2C (u8 * lpReg, u_short wIregIndex, u8 byVal)
173 int writestat; /* status for return */
175 /* read 32 bit IIC_CSR2 register data into union */
177 ReadMReg((lpReg + IIC_CSR2), iic_csr2_r.reg);
179 iic_csr2_r.fld.DIR_RD = 0; /* for write operation */
180 iic_csr2_r.fld.DIR_ADDR = wIregIndex; /* I2C address of I2C register: */
181 iic_csr2_r.fld.DIR_WR_DATA = byVal; /* 8 bit data to be written to I2C reg */
182 iic_csr2_r.fld.NEW_CYCLE = 1; /* will start a direct I2C cycle: */
184 /* xfer union data into 32 bit IIC_CSR2 register */
186 WriteMReg((lpReg + IIC_CSR2), iic_csr2_r.reg);
188 /* wait for IIC cycle to finish */
190 writestat = wait_ibsyclr( lpReg );
191 return writestat; /* return with status */
194 /***********************************************************************
197 This function handles reading from 8-bit DT3155 registers
199 1st parameter is pointer to 32-bit register base address
200 2nd parameter is reg. index;
201 3rd is adrs of value to be read
203 Returns TRUE - Successful completion
204 FALSE - Timeout error - cycle did not complete!
205 ***********************************************************************/
206 int ReadI2C (u8 * lpReg, u_short wIregIndex, u8 * byVal)
208 int writestat; /* status for return */
210 /* read 32 bit IIC_CSR2 register data into union */
211 ReadMReg((lpReg + IIC_CSR2), iic_csr2_r.reg);
213 /* for read operation */
214 iic_csr2_r.fld.DIR_RD = 1;
216 /* I2C address of I2C register: */
217 iic_csr2_r.fld.DIR_ADDR = wIregIndex;
219 /* will start a direct I2C cycle: */
220 iic_csr2_r.fld.NEW_CYCLE = 1;
222 /* xfer union's data into 32 bit IIC_CSR2 register */
223 WriteMReg((lpReg + IIC_CSR2), iic_csr2_r.reg);
225 /* wait for IIC cycle to finish */
226 writestat = wait_ibsyclr(lpReg);
228 /* Next 2 commands read 32 bit IIC_CSR1 register's data into union */
229 /* first read data is in IIC_CSR1 */
230 ReadMReg((lpReg + IIC_CSR1), iic_csr1_r.reg);
232 /* now get data u8 out of register */
233 *byVal = (u8) iic_csr1_r.fld.RD_DATA;
235 return writestat; /* return with status */