Commit 118e124d authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

dev: rename ltc6950 driver to ltc695x (supports more than one device)

parent 78486bb6
......@@ -24,7 +24,7 @@ obj-$(CONFIG_EMBEDDED_NODE) += \
dev/clock_monitor.o \
dev/spi_flash.o \
dev/iuart.o \
dev/ltc6950.o \
dev/ltc695x.o \
dev/ad9520.o \
dev/i2c_eeprom.o \
dev/storage.o \
......
......@@ -20,17 +20,18 @@
#include <stdint.h>
#include <stdio.h>
#include <sys/errno.h>
#include "dev/ltc6950.h"
#include "dev/ltc695x.h"
int ltc6950_init( struct ltc6950_device *dev, struct spi_bus *bus )
int ltc695x_init( struct ltc695x_device *dev, struct spi_bus *bus )
{
dev->bus = bus;
return 0;
}
// Read from LTC6950 via SPI
uint8_t ltc6950_read(struct ltc6950_device *dev, uint32_t reg) {
// Read from LTC695x via SPI
uint8_t ltc695x_read(struct ltc695x_device *dev, uint32_t reg) {
uint8_t rv;
bb_spi_cs(dev->bus, 1);
bb_spi_write( dev->bus, (reg << 1) | 1, 8);
......@@ -39,28 +40,94 @@ uint8_t ltc6950_read(struct ltc6950_device *dev, uint32_t reg) {
return rv;
}
void ltc6950_write(struct ltc6950_device *dev, uint32_t reg, uint8_t value) {
void ltc695x_write(struct ltc695x_device *dev, uint32_t reg, uint8_t value) {
bb_spi_cs(dev->bus, 1);
bb_spi_write( dev->bus, (reg << 1), 8);
bb_spi_write(dev->bus, value, 8);
bb_spi_cs(dev->bus, 0);
};
#define LTC6950_R0_LOCK (1<<2)
#define LTC695x_R0_LOCK (1<<2)
int ltc6950_configure(struct ltc6950_device *dev, struct ltc6950_config* cfg)
int ltc695x_configure(struct ltc695x_device *dev, struct ltc695x_config* cfg)
{
int i;
for(i = 0; i < cfg->n_regs; i++) {
// pp_printf("LTC write %x %x\n", cfg->regs[i].addr, cfg->regs[i].value);
ltc6950_write(dev, cfg->regs[i].addr, cfg->regs[i].value);
ltc695x_write(dev, cfg->regs[i].addr, cfg->regs[i].value);
}
}
#define LTC6953_PD_NORMAL (0)
#define LTC6953_PD_MUTE (1)
#define LTC6953_PD_OUTPUT (2)
#define LTC6953_PD_OUTPUT_AND_DIVIDER (3)
#define LTC6953_OR0_MP_DIV_MASK (0xf8)
#define LTC6953_OR0_MP_DIV_SHIFT (3)
#define LTC6953_OR0_MD_DIV_MASK (0x7)
#define LTC6953_OR0_MD_DIV_SHIFT (0)
#define LTC6953_OR1_SRQEN (1<<7)
#define LTC6953_OR1_OINV (1<<4)
#define LTC6953_OR1_MODE_MASK (0x60)
#define LTC6953_OR1_MODE_SHIFT (5)
#define LTC6953_OR1_MODE_
int ltc6953_set_pdown( struct ltc695x_device *dev, int out, int pd )
{
int shift = (out & 0x3) * 2;
int reg = 0x3 + (out / 4);
uint8_t r = ltc695x_read(dev, reg);
r &= ~( 0x3 << shift );
r |= pd << shift;
dev_dbg("ltc6953 out %d [addr %x mask %x r %x] PD = %d\n", out, reg, shift, r, pd );
ltc695x_write(dev, reg, r );
return 0;
}
int ltc6953_enable_output( struct ltc695x_device *dev, int output, int enabled )
{
return ltc6953_set_pdown( dev, output, enabled ? LTC6953_PD_NORMAL : LTC6953_PD_OUTPUT );
}
int ltc6953_configure_output( struct ltc695x_device *dev, int output, int divider, int invert )
{
uint8_t div_mp, div_md;
//for(;;)
dev_dbg("ltc6953 out %d div=%d inv=%d\n", output, divider, invert );
switch(divider)
{
uint8_t r0 = ltc6950_read( dev, 0 );
//pp_printf("tlc r0 = %x\n", r0 );
timer_delay_ms(100);
case 1: div_mp = 0; div_md = 1; break;
case 2: div_mp = 1; div_md = 1; break;
case 4: div_mp = 3; div_md = 1; break;
case 8: div_mp = 7; div_md = 1; break;
case 16: div_mp = 15; div_md = 1; break;
case 10: div_mp = 9; div_md = 1; break;
default: return -EINVAL; // unsupported divider
}
uint8_t or0 = (div_mp << LTC6953_OR0_MP_DIV_SHIFT) | (div_md << LTC6953_OR0_MD_DIV_SHIFT);
uint8_t or1 = invert ? LTC6953_OR1_OINV : 0;
int base = (output * 4 + 0xc);
dev_dbg("ltc6953 r%02x = %02x\n", base+0, or0 );
dev_dbg("ltc6953 r%02x = %02x\n", base+1, or1 );
ltc695x_write( dev, base + 0, or0 );
ltc695x_write( dev, base + 1, or1 );
return 0;
}
\ No newline at end of file
......@@ -18,8 +18,8 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __LTC6950_H
#define __LTC6950_H
#ifndef __LTC695X_H
#define __LTC695X_H
#include <stdint.h>
#include <stdio.h>
......@@ -27,24 +27,27 @@
#include "dev/gpio.h"
#include "dev/bb_spi.h"
struct ltc6950_device {
struct ltc695x_device {
struct spi_bus *bus;
};
struct ltc6950_config_reg {
struct ltc695x_config_reg {
uint16_t addr;
uint8_t value;
};
struct ltc6950_config {
struct ltc695x_config {
int n_regs;
struct ltc6950_config_reg regs[];
struct ltc695x_config_reg regs[];
};
int ltc6950_init( struct ltc6950_device *dev, struct spi_bus *bus );
uint8_t ltc6950_read(struct ltc6950_device *dev, uint32_t reg);
void ltc6950_write(struct ltc6950_device *dev, uint32_t reg, uint8_t value);
int ltc6950_configure(struct ltc6950_device *dev, struct ltc6950_config* cfg);
int ltc695x_init( struct ltc695x_device *dev, struct spi_bus *bus );
uint8_t ltc695x_read(struct ltc695x_device *dev, uint32_t reg);
void ltc695x_write(struct ltc695x_device *dev, uint32_t reg, uint8_t value);
int ltc695x_configure(struct ltc695x_device *dev, struct ltc695x_config* cfg);
int ltc6953_enable_output( struct ltc695x_device *dev, int output, int enabled );
int ltc6953_configure_output( struct ltc695x_device *dev, int output, int divider, int invert );
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment