1/* 2 * L3 code 3 * 4 * Copyright (C) 2008, Christian Pellegrin <chripell@evolware.org> 5 * 6 * This program is free software; you can redistribute it and/or modify 7 * it under the terms of the GNU General Public License version 2 as 8 * published by the Free Software Foundation. 9 * 10 * 11 * based on: 12 * 13 * L3 bus algorithm module. 14 * 15 * Copyright (C) 2001 Russell King, All Rights Reserved. 16 * 17 * 18 */ 19 20#include <linux/module.h> 21#include <linux/kernel.h> 22#include <linux/delay.h> 23 24#include <sound/l3.h> 25 26/* 27 * Send one byte of data to the chip. Data is latched into the chip on 28 * the rising edge of the clock. 29 */ 30static void sendbyte(struct l3_pins *adap, unsigned int byte) 31{ 32 int i; 33 34 for (i = 0; i < 8; i++) { 35 adap->setclk(0); 36 udelay(adap->data_hold); 37 adap->setdat(byte & 1); 38 udelay(adap->data_setup); 39 adap->setclk(1); 40 udelay(adap->clock_high); 41 byte >>= 1; 42 } 43} 44 45/* 46 * Send a set of bytes to the chip. We need to pulse the MODE line 47 * between each byte, but never at the start nor at the end of the 48 * transfer. 49 */ 50static void sendbytes(struct l3_pins *adap, const u8 *buf, 51 int len) 52{ 53 int i; 54 55 for (i = 0; i < len; i++) { 56 if (i) { 57 udelay(adap->mode_hold); 58 adap->setmode(0); 59 udelay(adap->mode); 60 } 61 adap->setmode(1); 62 udelay(adap->mode_setup); 63 sendbyte(adap, buf[i]); 64 } 65} 66 67int l3_write(struct l3_pins *adap, u8 addr, u8 *data, int len) 68{ 69 adap->setclk(1); 70 adap->setdat(1); 71 adap->setmode(1); 72 udelay(adap->mode); 73 74 adap->setmode(0); 75 udelay(adap->mode_setup); 76 sendbyte(adap, addr); 77 udelay(adap->mode_hold); 78 79 sendbytes(adap, data, len); 80 81 adap->setclk(1); 82 adap->setdat(1); 83 adap->setmode(0); 84 85 return len; 86} 87EXPORT_SYMBOL_GPL(l3_write); 88 89MODULE_DESCRIPTION("L3 bit-banging driver"); 90MODULE_AUTHOR("Christian Pellegrin <chripell@evolware.org>"); 91MODULE_LICENSE("GPL"); 92