--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2009 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief Configuration file for the TAS5706A module.
+ *
+ * \version $Id$
+ * \author Luca Ottaviano <lottaviano@develer.com>
+ */
+
+#ifndef CFG_TAS5706A_H
+#define CFG_TAS5706A_H
+
+/**
+ * Maximum output volume for TAS chip [dB].
+ *
+ * $WIZ$ type = "int"
+ * $WIZ$ min = -100
+ * $WIZ$ max = 24
+ * $WIZ$ supports = "at91"
+ */
+#define CONFIG_TAS_MAX_VOL -39
+
+#endif /* CFG_TAS5706A_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2009 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief TAS5706A Power DAC i2c driver.
+ *
+ *
+ * \version $Id$
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+#include "tas5706a.h"
+#include <cfg/module.h>
+
+#include <drv/i2c.h>
+#include <drv/timer.h>
+
+#include "hw/hw_tas5706a.h"
+#include "cfg/cfg_tas5706a.h"
+
+#define TAS_ADDR 0x36
+
+typedef uint8_t tas_addr_t;
+
+static bool tas5706a_send(tas_addr_t addr, const void *buf, size_t len)
+{
+ bool ret = i2c_start_w(TAS_ADDR) && i2c_put(addr) && i2c_send(buf, len);
+ i2c_stop();
+ return ret;
+}
+
+INLINE bool tas5706a_putc(tas_addr_t addr, uint8_t ch)
+{
+ return tas5706a_send(addr, &ch, sizeof(ch));
+}
+
+static bool tas5706a_recv(tas_addr_t addr, void *buf, size_t len)
+{
+ bool ret = i2c_start_w(TAS_ADDR) && i2c_put(addr) && i2c_start_r(TAS_ADDR) && i2c_recv(buf, len);
+ i2c_stop();
+ return ret;
+}
+
+INLINE int tas5706a_getc(tas_addr_t addr)
+{
+ uint8_t ch;
+ if (tas5706a_recv(addr, &ch, sizeof(ch)))
+ return (int)(uint8_t)ch;
+ else
+ return EOF;
+}
+
+#define TRIM_REG 0x1B
+#define SYS_REG2 0x05
+#define VOLUME_REG 0x07
+#define MUTE_VOL 0xFF
+
+#define DB_TO_REG(db) ((24 - (db)) * 2)
+
+void tas5706a_init(void)
+{
+ MOD_CHECK(i2c);
+ MOD_CHECK(timer);
+ TAS5706A_PIN_INIT();
+ timer_delay(200);
+ TAS5706A_SETPOWERDOWN(false);
+ TAS5706A_SETMUTE(false);
+ TAS5706A_MCLK_INIT();
+ timer_delay(2);
+ TAS5706A_SETRESET(false);
+ timer_delay(20);
+ tas5706a_putc(TRIM_REG, 0x00);
+
+ tas5706a_putc(VOLUME_REG, DB_TO_REG(CONFIG_TAS_MAX_VOL));
+
+ /* Unmute */
+ tas5706a_putc(SYS_REG2, 0);
+}
+
+#define CH1_VOL_REG 0x08
+#define CH2_VOL_REG 0x09
+#define CH3_VOL_REG 0x0A
+#define CH4_VOL_REG 0x0B
+
+void tas5706a_setVolume(Tas5706aCh ch, tas5706a_vol_t vol)
+{
+ ASSERT(ch < TAS_CNT);
+ ASSERT(vol <= TAS_VOL_MAX);
+
+ tas_addr_t addr1, addr2;
+
+ switch(ch)
+ {
+ case TAS_CH1:
+ addr1 = CH1_VOL_REG;
+ addr2 = CH3_VOL_REG;
+ break;
+ case TAS_CH2:
+ addr1 = CH2_VOL_REG;
+ addr2 = CH4_VOL_REG;
+ break;
+ default:
+ ASSERT(0);
+ return;
+ }
+
+ uint8_t vol_att = 0xff - ((vol * 0xff) / TAS_VOL_MAX);
+
+ tas5706a_putc(addr1, vol_att);
+ tas5706a_putc(addr2, vol_att);
+}
+
+void tas5706a_setLowPower(bool val)
+{
+ TAS5706A_SETPOWERDOWN(val);
+ TAS5706A_SETMUTE(val);
+}
+
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2009 Develer S.r.l. (http://www.develer.com/)
+ *
+ * -->
+ *
+ * \brief TAS5706A Power DAC i2c driver.
+ *
+ *
+ * \version $Id$
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+#ifndef DRV_TAS5706A_H
+#define DRV_TAS5706A_H
+
+#include <cfg/compiler.h>
+
+typedef enum Tas5706aCh
+{
+ TAS_CH1,
+ TAS_CH2,
+ TAS_CNT,
+} Tas5706aCh;
+
+/**
+ * TAS minimum volume (%).
+ */
+#define TAS_VOL_MIN 0
+
+/**
+ * TAS maximum volume (%).
+ */
+#define TAS_VOL_MAX 100
+
+typedef uint8_t tas5706a_vol_t;
+
+/**
+ * Set the volume for the specified channel.
+ *
+ * The volume must be expressed in % and will be at maximum CONFIG_TAS_MAX_VOL.
+ *
+ * \param ch The channel to be controlled.
+ * \param vol The volume you want to set.
+ */
+void tas5706a_setVolume(Tas5706aCh ch, tas5706a_vol_t vol);
+
+/**
+ * Initialize the TAS chip.
+ */
+void tas5706a_init(void);
+
+/**
+ * Set TAS chip to low power mode.
+ *
+ * When in low power mode, the TAS will not play any sound. You should put the TAS chip in low
+ * power whenever possible to prevent overheating and to save power.
+ *
+ * \param val True if you want to enable low power mode, false otherwise.
+ */
+void tas5706a_setLowPower(bool val);
+
+#endif /* DRV_TAS5706A_H */
--- /dev/null
+/**
+ * \file
+ * <!--
+ * This file is part of BeRTOS.
+ *
+ * Bertos is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ * As a special exception, you may use this file as part of a free software
+ * library without restriction. Specifically, if other files instantiate
+ * templates or use macros or inline functions from this file, or you compile
+ * this file and link it with other files to produce an executable, this
+ * file does not by itself cause the resulting executable to be covered by
+ * the GNU General Public License. This exception does not however
+ * invalidate any other reasons why the executable file might be covered by
+ * the GNU General Public License.
+ *
+ * Copyright 2009 Develer S.r.l. (http://www.develer.com/)
+ * All Rights Reserved.
+ * -->
+ *
+ * \brief HW pin handling.
+ *
+ * \version $Id$
+ *
+ * \author Francesco Sacchi <batt@develer.com>
+ */
+
+#ifndef HW_TAS5706A_H
+#define HW_TAS5706A_H
+
+#include <io/arm.h>
+#include <cfg/macros.h>
+
+#define TAS5706A_SETPOWERDOWN(val) do { if (val) PIOA_CODR = BV(6); else PIOA_SODR = BV(6); } while (0)
+#define TAS5706A_SETRESET(val) do { if (val) PIOA_CODR = BV(7); else PIOA_SODR = BV(7); } while (0)
+#define TAS5706A_SETMUTE(val) do { if (val) PIOA_CODR = BV(8); else PIOA_SODR = BV(8); } while (0)
+
+#define TAS5706A_PIN_INIT() \
+ do { \
+ TAS5706A_SETPOWERDOWN(true); \
+ TAS5706A_SETRESET(true); \
+ TAS5706A_SETMUTE(true); \
+ PIOA_PER = BV(6) | BV(7) | BV(8); \
+ PIOA_OER = BV(6) | BV(7) | BV(8); \
+ } while (0)
+
+#define TAS5706A_MCLK_INIT() \
+ do { \
+ PIOA_PDR = BV(2); /* enable PWM pin */ \
+ PWM_CMR2 = 0; /* set prescaler to MCK, left aligned, start with low level */ \
+ PWM_CPRD2 = 4; /* 11.2896 MHz MCLK */ \
+ PWM_CDTY2 = 2; /* 50% duty */ \
+ PWM_ENA = BV(2); /* Enable PWM on MCLK pin */ \
+ } while(0)
+
+
+#endif /* HW_TAS5706A_H */