wm8731.c
Go to the documentation of this file.
00001 00039 #include "wm8731.h" 00040 00041 #include "hw/hw_wm8731.h" 00042 #include "cfg/cfg_wm8731.h" 00043 00044 // Define logging setting (for cfg/log.h module). 00045 #define LOG_LEVEL WM8731_LOG_LEVEL 00046 #define LOG_FORMAT WM8731_LOG_FORMAT 00047 #include <cfg/log.h> 00048 #include <cfg/macros.h> 00049 00050 #include <cpu/irq.h> 00051 00052 #include <drv/i2c.h> 00053 00054 00055 static void wm8731_write(Wm8731 *ctx, uint8_t reg, uint16_t value) 00056 { 00057 00058 uint16_t tmp = ((reg & 0x7F) << 9) | (value & 0x1FF); 00059 00060 i2c_start_w(ctx->i2c, ctx->addr, 2, I2C_STOP); 00061 i2c_putc(ctx->i2c, (uint8_t)((tmp & 0xFF00) >> 8)); 00062 i2c_putc(ctx->i2c, (uint8_t)(tmp & 0xFF)); 00063 00064 int err = i2c_error(ctx->i2c); 00065 if (err) 00066 LOG_ERR("Error[%d] while send command to codec.\n", err); 00067 00068 } 00069 00070 #define RANGECONV(data, y1, y2) (((((int32_t)(data)) * ((y2) - (y1))) / ((1 << 8) - 1)) + (y1)) 00071 void wm8731_setVolume(Wm8731 *ctx, uint16_t device, uint8_t volume) 00072 { 00073 uint16_t value; 00074 00075 if (device & WM8731_LINE_IN) 00076 { 00077 if (!volume) 00078 { 00079 wm8731_write(ctx, WM8731_REG_RIGHT_LINEIN, BV(WM8731_LINMUTE_BIT) | BV(WM8731_RLINBOTH_BIT)); 00080 wm8731_write(ctx, WM8731_REG_LEFT_LINEIN, BV(WM8731_LINMUTE_BIT) | BV(WM8731_LRINBOTH_BIT)); 00081 } 00082 00083 value = DIV_ROUND(volume * WM8731_LINVOL_BITS_MASK, 100); 00084 00085 wm8731_write(ctx, WM8731_REG_RIGHT_LINEIN, ~BV(WM8731_LINMUTE_BIT) | value); 00086 wm8731_write(ctx, WM8731_REG_LEFT_LINEIN, ~BV(WM8731_RINMUTE_BIT) | value); 00087 LOG_INFO("Set LINE IN vol[%d]%% raw[%d]\n", volume, value); 00088 } 00089 00090 if (device & WM8731_HEADPHONE) 00091 { 00092 value = DIV_ROUND(volume * WM8731_RHPVOL_BITS_MASK, 100); 00093 00094 wm8731_write(ctx, WM8731_REG_RIGHT_HPOUT, value | BV(WM8731_RZCEN_BIT) | BV(WM8731_RLHPBOTH_BIT)); 00095 wm8731_write(ctx, WM8731_REG_LEFT_HPOUT, value | BV(WM8731_LZCEN_BIT) | BV(WM8731_LRHPBOTH_BIT)); 00096 LOG_INFO("Set HEADPHONE vol[%d]%% raw[%d]\n", volume, value); 00097 } 00098 00099 } 00100 00101 void wm8731_powerOn(Wm8731 *ctx) 00102 { 00103 LOG_INFO("Power on codec\n"); 00104 wm8731_write(ctx, WM8731_REG_PWDOWN_CTRL, ~BV(WM8731_POWEROFF_BIT) & 0x7F); 00105 } 00106 00107 void wm8731_powerOff(Wm8731 *ctx) 00108 { 00109 LOG_INFO("Power off codec\n"); 00110 wm8731_write(ctx, WM8731_REG_PWDOWN_CTRL, BV(WM8731_POWEROFF_BIT) & 0x7F); 00111 } 00112 00113 void wm8731_powerOnDevices(Wm8731 *ctx, uint16_t device) 00114 { 00115 wm8731_write(ctx, WM8731_REG_PWDOWN_CTRL, ~device & 0x7F); 00116 LOG_INFO("Turn on the devices[%x]\n", ~device & 0x7F); 00117 } 00118 00119 void wm8731_powerOffDevices(Wm8731 *ctx, uint16_t device) 00120 { 00121 wm8731_write(ctx, WM8731_REG_PWDOWN_CTRL, device & 0x7F); 00122 LOG_INFO("Turn off the devices[%x]\n", device); 00123 } 00124 00125 void wm8731_init(Wm8731 *ctx, I2c *i2c, uint8_t codec_addr) 00126 { 00127 ctx->i2c = i2c; 00128 ctx->addr = codec_addr; 00129 00130 WM8731_PIN_INIT(); 00131 WM8731_MCLK_INIT(); 00132 00133 LOG_INFO("Init WM8731 codec.\n"); 00134 00135 /* Reset codec and active it */ 00136 wm8731_write(ctx, WM8731_REG_RESET, 0); 00137 00138 00139 /* Configure the codec */ 00140 wm8731_write(ctx, WM8731_REG_DIGITAL_PATH_CTRL, CONFIG_WM8731_DEEMP | CONFIG_WM8731_DAPC | (CONFIG_WM8731_DACMU << WM8731_DACMU)); 00141 00142 #if CONFIG_WM8731_MICBOOST 00143 wm8731_write(ctx, WM8731_REG_ANALOGUE_PATH_CTRL, BV(WM8731_MICBOOST) | CONFIG_WM8731_INSEL | CONFIG_WM8731_BYPASS | CONFIG_WM8731_SIDEATT); 00144 #else 00145 wm8731_write(ctx, WM8731_REG_ANALOGUE_PATH_CTRL, (CONFIG_WM8731_INSEL | CONFIG_WM8731_BYPASS | CONFIG_WM8731_SIDEATT) & ~BV(WM8731_MICBOOST)); 00146 #endif 00147 00148 #if CONFIG_WM8731_MS 00149 wm8731_write(ctx, WM8731_REG_DA_INTERFACE_FORMAT, CONFIG_WM8731_INTERFACE_FORMAT | CONFIG_WM8731_IWL_BITS | BV(WM8731_MS_BIT)); 00150 #else 00151 wm8731_write(ctx, WM8731_REG_DA_INTERFACE_FORMAT, 00152 (CONFIG_WM8731_INTERFACE_FORMAT | CONFIG_WM8731_IWL_BITS | BV(WM8731_MS_BIT)) & ~BV(WM8731_MS_BIT)); 00153 #endif 00154 00155 wm8731_write(ctx, WM8731_REG_SAMPLECTRL, CONFIG_WM8731_SAMPLING_RATES); 00156 00157 /* By default we turn on all devices and disable only the outclock */ 00158 wm8731_write(ctx, WM8731_REG_ACTIVE_CTRL, 1); 00159 wm8731_write(ctx, WM8731_REG_PWDOWN_CTRL, 0x40); 00160 }
![(please configure the [header_logo] section in trac.ini)](/chrome/site/bertos_logo.png)