1/*- 2 * Copyright (c) 1998, 2001 Nicolas Souchu 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h>
| 1/*- 2 * Copyright (c) 1998, 2001 Nicolas Souchu 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * 2. Redistributions in binary form must reproduce the above copyright 11 * notice, this list of conditions and the following disclaimer in the 12 * documentation and/or other materials provided with the distribution. 13 * 14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24 * SUCH DAMAGE. 25 */ 26 27#include <sys/cdefs.h>
|
123{ 124 struct bktr_softc *bktr_sc = (struct bktr_softc *)device_get_softc(dev); 125 struct bktr_i2c_softc *sc = &bktr_sc->i2c_sc; 126 int error = 0; 127 128 /* test each time if we already have/haven't the iicbus 129 * to avoid deadlocks 130 */ 131 switch (index) { 132 case SMB_REQUEST_BUS: 133 /* XXX test & set */ 134 if (!sc->bus_owned) { 135 sc->bus_owned = 1; 136 } else 137 error = EWOULDBLOCK; 138 break; 139 140 case SMB_RELEASE_BUS: 141 /* XXX test & set */ 142 if (sc->bus_owned) { 143 sc->bus_owned = 0; 144 } else 145 error = EINVAL; 146 break; 147 148 default: 149 error = EINVAL; 150 } 151 152 return (error); 153} 154 155int bti2c_iic_callback(device_t dev, int index, caddr_t *data) 156{ 157 struct bktr_softc *bktr_sc = (struct bktr_softc *)device_get_softc(dev); 158 struct bktr_i2c_softc *sc = &bktr_sc->i2c_sc; 159 int error = 0; 160 161 /* test each time if we already have/haven't the smbus 162 * to avoid deadlocks 163 */ 164 switch (index) { 165 case IIC_REQUEST_BUS: 166 /* XXX test & set */ 167 if (!sc->bus_owned) { 168 sc->bus_owned = 1; 169 } else 170 error = EWOULDBLOCK; 171 break; 172 173 case IIC_RELEASE_BUS: 174 /* XXX test & set */ 175 if (sc->bus_owned) { 176 sc->bus_owned = 0; 177 } else 178 error = EINVAL; 179 break; 180 181 default: 182 error = EINVAL; 183 } 184 185 return (error); 186} 187 188int bti2c_iic_reset(device_t dev, u_char speed, u_char addr, u_char * oldaddr) 189{ 190 if (oldaddr) 191 *oldaddr = 0; /* XXX */ 192 193 return (IIC_ENOADDR); 194} 195 196void bti2c_iic_setsda(device_t dev, int val) 197{ 198 struct bktr_softc *sc = (struct bktr_softc *)device_get_softc(dev); 199 int clock; 200 201 clock = INL(sc, BKTR_I2C_DATA_CTL) & 0x2; 202 203 if (val) 204 OUTL(sc, BKTR_I2C_DATA_CTL, clock | 1); 205 else 206 OUTL(sc, BKTR_I2C_DATA_CTL, clock); 207 208 DELAY(I2C_DELAY); 209 210 return; 211} 212 213void bti2c_iic_setscl(device_t dev, int val) 214{ 215 struct bktr_softc *sc = (struct bktr_softc *)device_get_softc(dev); 216 int data; 217 218 data = INL(sc, BKTR_I2C_DATA_CTL) & 0x1; 219 220 if (val) 221 OUTL(sc, BKTR_I2C_DATA_CTL, 0x2 | data); 222 else 223 OUTL(sc, BKTR_I2C_DATA_CTL, data); 224 225 DELAY(I2C_DELAY); 226 227 return; 228} 229 230int 231bti2c_iic_getsda(device_t dev) 232{ 233 struct bktr_softc *sc = (struct bktr_softc *)device_get_softc(dev); 234 235 return (INL(sc,BKTR_I2C_DATA_CTL) & 0x1); 236} 237 238int 239bti2c_iic_getscl(device_t dev) 240{ 241 return (0); 242} 243 244static int 245bti2c_write(struct bktr_softc *sc, u_long data) 246{ 247 u_long x; 248 249 /* clear status bits */ 250 OUTL(sc, BKTR_INT_STAT, (BT848_INT_RACK | BT848_INT_I2CDONE)); 251 252 BTI2C_DEBUG(printf("w%lx", data)); 253 254 /* write the address and data */ 255 OUTL(sc, BKTR_I2C_DATA_CTL, data); 256 257 /* wait for completion */ 258 for ( x = 0x7fffffff; x; --x ) { /* safety valve */ 259 if ( INL(sc, BKTR_INT_STAT) & BT848_INT_I2CDONE ) 260 break; 261 } 262 263 /* check for ACK */ 264 if ( !x || !( INL(sc, BKTR_INT_STAT) & BT848_INT_RACK) ) { 265 BTI2C_DEBUG(printf("%c%c", (!x)?'+':'-', 266 (!( INL(sc, BKTR_INT_STAT) & BT848_INT_RACK))?'+':'-')); 267 return (SMB_ENOACK); 268 } 269 BTI2C_DEBUG(printf("+")); 270 271 /* return OK */ 272 return( 0 ); 273} 274 275int 276bti2c_smb_writeb(device_t dev, u_char slave, char cmd, char byte) 277{ 278 struct bktr_softc *sc = (struct bktr_softc *)device_get_softc(dev); 279 u_long data; 280 281 data = ((slave & 0xff) << 24) | ((byte & 0xff) << 16) | (u_char)cmd; 282 283 return (bti2c_write(sc, data)); 284} 285 286/* 287 * byte1 becomes low byte of word 288 * byte2 becomes high byte of word 289 */ 290int 291bti2c_smb_writew(device_t dev, u_char slave, char cmd, short word) 292{ 293 struct bktr_softc *sc = (struct bktr_softc *)device_get_softc(dev); 294 u_long data; 295 char low, high; 296 297 low = (char)(word & 0xff); 298 high = (char)((word & 0xff00) >> 8); 299 300 data = ((slave & 0xff) << 24) | ((low & 0xff) << 16) | 301 ((high & 0xff) << 8) | BT848_DATA_CTL_I2CW3B | (u_char)cmd; 302 303 return (bti2c_write(sc, data)); 304} 305 306/* 307 * The Bt878 and Bt879 differed on the treatment of i2c commands 308 */ 309int 310bti2c_smb_readb(device_t dev, u_char slave, char cmd, char *byte) 311{ 312 struct bktr_softc *sc = (struct bktr_softc *)device_get_softc(dev); 313 u_long x; 314 315 /* clear status bits */ 316 OUTL(sc,BKTR_INT_STAT, (BT848_INT_RACK | BT848_INT_I2CDONE)); 317 318 OUTL(sc,BKTR_I2C_DATA_CTL, ((slave & 0xff) << 24) | (u_char)cmd);; 319 320 BTI2C_DEBUG(printf("r%lx/", (u_long)(((slave & 0xff) << 24) | (u_char)cmd))); 321 322 /* wait for completion */ 323 for ( x = 0x7fffffff; x; --x ) { /* safety valve */ 324 if ( INL(sc,BKTR_INT_STAT) & BT848_INT_I2CDONE ) 325 break; 326 } 327 328 /* check for ACK */ 329 if ( !x || !(INL(sc,BKTR_INT_STAT) & BT848_INT_RACK) ) { 330 BTI2C_DEBUG(printf("r%c%c", (!x)?'+':'-', 331 (!( INL(sc,BKTR_INT_STAT) & BT848_INT_RACK))?'+':'-')); 332 return (SMB_ENOACK); 333 } 334 335 *byte = (char)((INL(sc,BKTR_I2C_DATA_CTL) >> 8) & 0xff); 336 BTI2C_DEBUG(printf("r%x+", *byte)); 337 338 return (0); 339} 340
| 123{ 124 struct bktr_softc *bktr_sc = (struct bktr_softc *)device_get_softc(dev); 125 struct bktr_i2c_softc *sc = &bktr_sc->i2c_sc; 126 int error = 0; 127 128 /* test each time if we already have/haven't the iicbus 129 * to avoid deadlocks 130 */ 131 switch (index) { 132 case SMB_REQUEST_BUS: 133 /* XXX test & set */ 134 if (!sc->bus_owned) { 135 sc->bus_owned = 1; 136 } else 137 error = EWOULDBLOCK; 138 break; 139 140 case SMB_RELEASE_BUS: 141 /* XXX test & set */ 142 if (sc->bus_owned) { 143 sc->bus_owned = 0; 144 } else 145 error = EINVAL; 146 break; 147 148 default: 149 error = EINVAL; 150 } 151 152 return (error); 153} 154 155int bti2c_iic_callback(device_t dev, int index, caddr_t *data) 156{ 157 struct bktr_softc *bktr_sc = (struct bktr_softc *)device_get_softc(dev); 158 struct bktr_i2c_softc *sc = &bktr_sc->i2c_sc; 159 int error = 0; 160 161 /* test each time if we already have/haven't the smbus 162 * to avoid deadlocks 163 */ 164 switch (index) { 165 case IIC_REQUEST_BUS: 166 /* XXX test & set */ 167 if (!sc->bus_owned) { 168 sc->bus_owned = 1; 169 } else 170 error = EWOULDBLOCK; 171 break; 172 173 case IIC_RELEASE_BUS: 174 /* XXX test & set */ 175 if (sc->bus_owned) { 176 sc->bus_owned = 0; 177 } else 178 error = EINVAL; 179 break; 180 181 default: 182 error = EINVAL; 183 } 184 185 return (error); 186} 187 188int bti2c_iic_reset(device_t dev, u_char speed, u_char addr, u_char * oldaddr) 189{ 190 if (oldaddr) 191 *oldaddr = 0; /* XXX */ 192 193 return (IIC_ENOADDR); 194} 195 196void bti2c_iic_setsda(device_t dev, int val) 197{ 198 struct bktr_softc *sc = (struct bktr_softc *)device_get_softc(dev); 199 int clock; 200 201 clock = INL(sc, BKTR_I2C_DATA_CTL) & 0x2; 202 203 if (val) 204 OUTL(sc, BKTR_I2C_DATA_CTL, clock | 1); 205 else 206 OUTL(sc, BKTR_I2C_DATA_CTL, clock); 207 208 DELAY(I2C_DELAY); 209 210 return; 211} 212 213void bti2c_iic_setscl(device_t dev, int val) 214{ 215 struct bktr_softc *sc = (struct bktr_softc *)device_get_softc(dev); 216 int data; 217 218 data = INL(sc, BKTR_I2C_DATA_CTL) & 0x1; 219 220 if (val) 221 OUTL(sc, BKTR_I2C_DATA_CTL, 0x2 | data); 222 else 223 OUTL(sc, BKTR_I2C_DATA_CTL, data); 224 225 DELAY(I2C_DELAY); 226 227 return; 228} 229 230int 231bti2c_iic_getsda(device_t dev) 232{ 233 struct bktr_softc *sc = (struct bktr_softc *)device_get_softc(dev); 234 235 return (INL(sc,BKTR_I2C_DATA_CTL) & 0x1); 236} 237 238int 239bti2c_iic_getscl(device_t dev) 240{ 241 return (0); 242} 243 244static int 245bti2c_write(struct bktr_softc *sc, u_long data) 246{ 247 u_long x; 248 249 /* clear status bits */ 250 OUTL(sc, BKTR_INT_STAT, (BT848_INT_RACK | BT848_INT_I2CDONE)); 251 252 BTI2C_DEBUG(printf("w%lx", data)); 253 254 /* write the address and data */ 255 OUTL(sc, BKTR_I2C_DATA_CTL, data); 256 257 /* wait for completion */ 258 for ( x = 0x7fffffff; x; --x ) { /* safety valve */ 259 if ( INL(sc, BKTR_INT_STAT) & BT848_INT_I2CDONE ) 260 break; 261 } 262 263 /* check for ACK */ 264 if ( !x || !( INL(sc, BKTR_INT_STAT) & BT848_INT_RACK) ) { 265 BTI2C_DEBUG(printf("%c%c", (!x)?'+':'-', 266 (!( INL(sc, BKTR_INT_STAT) & BT848_INT_RACK))?'+':'-')); 267 return (SMB_ENOACK); 268 } 269 BTI2C_DEBUG(printf("+")); 270 271 /* return OK */ 272 return( 0 ); 273} 274 275int 276bti2c_smb_writeb(device_t dev, u_char slave, char cmd, char byte) 277{ 278 struct bktr_softc *sc = (struct bktr_softc *)device_get_softc(dev); 279 u_long data; 280 281 data = ((slave & 0xff) << 24) | ((byte & 0xff) << 16) | (u_char)cmd; 282 283 return (bti2c_write(sc, data)); 284} 285 286/* 287 * byte1 becomes low byte of word 288 * byte2 becomes high byte of word 289 */ 290int 291bti2c_smb_writew(device_t dev, u_char slave, char cmd, short word) 292{ 293 struct bktr_softc *sc = (struct bktr_softc *)device_get_softc(dev); 294 u_long data; 295 char low, high; 296 297 low = (char)(word & 0xff); 298 high = (char)((word & 0xff00) >> 8); 299 300 data = ((slave & 0xff) << 24) | ((low & 0xff) << 16) | 301 ((high & 0xff) << 8) | BT848_DATA_CTL_I2CW3B | (u_char)cmd; 302 303 return (bti2c_write(sc, data)); 304} 305 306/* 307 * The Bt878 and Bt879 differed on the treatment of i2c commands 308 */ 309int 310bti2c_smb_readb(device_t dev, u_char slave, char cmd, char *byte) 311{ 312 struct bktr_softc *sc = (struct bktr_softc *)device_get_softc(dev); 313 u_long x; 314 315 /* clear status bits */ 316 OUTL(sc,BKTR_INT_STAT, (BT848_INT_RACK | BT848_INT_I2CDONE)); 317 318 OUTL(sc,BKTR_I2C_DATA_CTL, ((slave & 0xff) << 24) | (u_char)cmd);; 319 320 BTI2C_DEBUG(printf("r%lx/", (u_long)(((slave & 0xff) << 24) | (u_char)cmd))); 321 322 /* wait for completion */ 323 for ( x = 0x7fffffff; x; --x ) { /* safety valve */ 324 if ( INL(sc,BKTR_INT_STAT) & BT848_INT_I2CDONE ) 325 break; 326 } 327 328 /* check for ACK */ 329 if ( !x || !(INL(sc,BKTR_INT_STAT) & BT848_INT_RACK) ) { 330 BTI2C_DEBUG(printf("r%c%c", (!x)?'+':'-', 331 (!( INL(sc,BKTR_INT_STAT) & BT848_INT_RACK))?'+':'-')); 332 return (SMB_ENOACK); 333 } 334 335 *byte = (char)((INL(sc,BKTR_I2C_DATA_CTL) >> 8) & 0xff); 336 BTI2C_DEBUG(printf("r%x+", *byte)); 337 338 return (0); 339} 340
|