A few questions about an audio CODEC

Thread Starter

Robert Murch

Joined Nov 2, 2015
43
Hello! So I have been tasked with a project and I am attempting to come to terms with the scope/breadth of it. To keep it simple, the Audio CODEC and amp for one of our devices has reached end of life. New replacement parts have been selected and some test equipment has been built and shipped to me. I need to figure out what new software changes must be made in order to get this new hardware working properly. Unfortunately, I have limited experience with hardware/software communication on embedded Linux systems. The majority of the team is working on a new product (including the hardware guys) and so I am on my own.

In any case, I have a few questions. The first question I have is given the current setup:

https://postimg.cc/6ycB4ngt

Is there a method of pinging this CODEC https://www.cirrus.com/products/wm8750/# in order to differentiate it from our old CODEC without changing any circuitry that I can not see? From what I can tell there is no obvious method. The idea is that we would like to be able to put new builds on old hardware if we need to. In a perfect world we could simply ping the device itself (as is) to tell if we are working with an older system or a newer one.

My second question is a bit more vague and I will be spending a lot of time in the coming weeks trying to redefine/answer it myself. However, in the meantime:

I am trying to figure out what I will need to do; what (steps/process) I need to take in order to get the new CODEC and amplifier working with the old code. From what I understand I will need a driver and I may be able to rework/tweak our old audio driver (running with ancient Linux kernal 2.6.35.14) or take a new updated driver for the new CODEC and tweak it to work with an older kernal. Maybe I should contact Digi to see if they already have an embedded linux machine driver for the wm8750 on the mx51. Maybe by some off chance they had helped some other client develop one but didn't include it in the sdk?

If anyone willing to help needs any more information I will do my best to provide it. I have datasheets for the new/old CODEC and amp. I have access to our old drivers and kernal package. I realize this question is rather vague and thus most likely reflects my poor understanding of hardware/software communication but then again I am a CS guy so this is slightly familiar but mostly hostile territory for me.

Edit: I am not sure why my image isn't showing: https://postimg.cc/6ycB4ngt
 
Last edited:

Papabravo

Joined Feb 24, 2006
16,512
You need to start with the control interface. Decide if you want to use the 3-wire control or the 2-wire control. This decision may be informed by the available hardware on your main processor. The very first piece of software you want to write is a little debugger program that is able to read and display each register in the device. Then it must be able to write each register in the device. You can get really fancy and decode the results of reading a register into individual bit fields. I used to eat this kind of stuff up when I worked at Wadia.

Once you have a handle on the new part you can tell if the old part is in by the lack of response or no response at all because there is no connection to the old part.

I'd almost be willing to do this for you for the right price.

Whoops. It looks like the control registers are Write Only. We used to make hilarious jokes about WOMs (Write Only Memories). Excuse me for living but this is just about the stupidest way to design a chip. I guess you'd have to make a shadow copy of the register set and update it each time you made a change. I can see this causing major audio problems if anything goes wrong with a data transfer. The only fix I can see is continuous updating of the registers in the CODEC. That way any malfunctions will be transitory as the correct value will be written every so many milliseconds.
 
Last edited:

Thread Starter

Robert Murch

Joined Nov 2, 2015
43
@Papabravo So I managed to find: wm8750.c and wm8753.c in our kernel. I am assuming that means I do not have to write a new CODEC? Which is good because it was a 2000 line program written by a senior developer for Texas Instruments..

"Whoops. It looks like the control registers are Write Only." - Is this information you gathered from the datasheet?

EDIT:

Since the codec driver for the wm8750 exists in our version of the kernel. Unfortunately, Digi does not provide the machine driver. The only machine driver that exists for the mx51 is the wm8753. There are also a few machine drivers for 3 stack boards and a sgtl5000 for the mx53. We are currently using DigiEL v5.6 but I have checked the latest mx51 release, v5.9, and nothing has changed.

I believe that in order to use the wm8750, I will have to create a custom machine driver and implement the hooks necessary to compile and use the driver in our kernel version does that sound about correct?
 
Last edited:

Papabravo

Joined Feb 24, 2006
16,512
@Papabravo So I managed to find: wm8750.c and wm8753.c in our kernel. I am assuming that means I do not have to write a new CODEC? Which is good because it was a 2000 line program written by a senior developer for Texas Instruments..

"Whoops. It looks like the control registers are Write Only." - Is this information you gathered from the datasheet?

EDIT:

Since the codec driver for the wm8750 exists in our version of the kernel. Unfortunately, Digi does not provide the machine driver. The only machine driver that exists for the mx51 is the wm8753 (our old codec). There are also a few machine drivers for 3 stack boards and a sgtl5000 for the mx53. We are currently using DigiEL v5.6 but I have checked the latest mx51 release, v5.9, and nothing has changed.

I believe that in order to use the wm8750, I will have to create a custom machine driver and implement the hooks necessary to compile and use the driver in our kernel version does that sound about correct?
A 2 part reply.
  1. I did gather from the datasheet that there is no way to read data back from the WM8750. Specifically the section on the "Control Interface" One mode looks like SPI, but unlike SPI there in no R/W bit in the control stream. Rather there is a 7-bit register address and 9 bits of data. In a true SPI interface the bit after the address bits would be a Read/Write (R/W) bit. Similarly on the I2C-like interface there does not appear to be a provision for turning the bus around after the ACK pulse and reading the register data.
  2. If you have an example you can work from and can see that the WM8753 is also a Write only device, you should be able to conjure up a new set of functions for the differences in the register map. I don't know how your system handles the fact that you cannot check the status of registers you've written. That is like a big REG FLAG screaming "UNRELIABLE" at the top of it's lungs. Maybe they implement a strategy for that and maybe they spray and pray. Whatever the case -- good luck with this project.
 
Last edited:

Thread Starter

Robert Murch

Joined Nov 2, 2015
43
@Papabravo The big problem that I am having is that I am unaware of all the pieces of the puzzle. The file I found wm8750.c is located in a directory called codecs. Should I take that to mean that it is not the driver? That would be odd because it's called "audio driver" Here is a snip of that file:

Code:
/*
* wm8750.c -- WM8750 ALSA SoC audio driver
*
* Copyright 2005 Openedhand Ltd.
*
* Author: Richard Purdie <richard@openedhand.com>
*
* Based on WM8753.c
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/i2c.h>
#include <linux/platform_device.h>
#include <linux/spi/spi.h>
#include <linux/slab.h>
#include <sound/core.h>
#include <sound/pcm.h>
#include <sound/pcm_params.h>
#include <sound/soc.h>
#include <sound/soc-dapm.h>
#include <sound/initval.h>

#include "wm8750.h"

/*
* wm8750 register cache
* We can't read the WM8750 register space when we
* are using 2 wire for device control, so we cache them instead.
*/
static const u16 wm8750_reg[] = {
   0x0097, 0x0097, 0x0079, 0x0079,  /*  0 */
   0x0000, 0x0008, 0x0000, 0x000a,  /*  4 */
   0x0000, 0x0000, 0x00ff, 0x00ff,  /*  8 */
   0x000f, 0x000f, 0x0000, 0x0000,  /* 12 */
   0x0000, 0x007b, 0x0000, 0x0032,  /* 16 */
   0x0000, 0x00c3, 0x00c3, 0x00c0,  /* 20 */
   0x0000, 0x0000, 0x0000, 0x0000,  /* 24 */
   0x0000, 0x0000, 0x0000, 0x0000,  /* 28 */
   0x0000, 0x0000, 0x0050, 0x0050,  /* 32 */
   0x0050, 0x0050, 0x0050, 0x0050,  /* 36 */
   0x0079, 0x0079, 0x0079,  /* 40 */
};

/* codec private data */
struct wm8750_priv {
   unsigned int sysclk;
   struct snd_soc_codec codec;
   u16 reg_cache[ARRAY_SIZE(wm8750_reg)];
};
Apparently, along with this codec there should be some kind of driver which was to referred to me as a "machine driver" file that I will need to manipulate?
 

Papabravo

Joined Feb 24, 2006
16,512
The file, such as it is, corresponds to two assertions that I have made. One is that you cannot read the registers of the device, and that is why you have a register cache in any piece of interface software. If this is not the driver you seek, it is certainly a fundamental part of it. I would dissect that file in detail by starting with a list of the functions, and writing a short précis on what each one does. From that exercise you should be able to answer your fundamental question, or at least identify what is missing -- if anything.

Also, you might try contacting the author of the header file whose email address is given. It would not be there if he didn't expect people to contact him.

Just to give you idea of a similar chip I have worked with:
The following chip was used in conjunction with an Atmel ATmega2561 for the Wadia 121.

http://www.wadia.com/ContentsFiles/Wadia 121 Brochure web.pdf

One of the problems I encountered with the I2C interface was an unexplained transmission fault. It would result in an incomplete transmission with no indication except VIOLENT volume changes. As a result we always checked volume settings after making them and occasionally made them twice.
 

Attachments

Last edited:

Thread Starter

Robert Murch

Joined Nov 2, 2015
43
@Papabravo I thought to contact him as well but it was 13 years ago so I wasn't sure. One thing that confuses me that you might be able to clear up for me. In the kernel-2.6.35.14 directory there is a config file. In that file there is a section 'Console display driver support' in which I found the config option 'CONFIG_SND_SOC_IMX_CCWMX51_WM8753=y' has been enabled. I assumed there would be an option for the wm8750 something like 'CONFIG_SND_SOC_IMX_CCWMX51_WM8750=y' but that option does not exist. I am assuming this is something that I would have to instantiate myself?
 

Papabravo

Joined Feb 24, 2006
16,512
@Papabravo I thought to contact him as well but it was 13 years ago so I wasn't sure. One thing that confuses me that you might be able to clear up for me. In the kernel-2.6.35.14 directory there is a config file. In that file there is a section 'Console display driver support' in which I found the config option 'CONFIG_SND_SOC_IMX_CCWMX51_WM8753=y' has been enabled. I assumed there would be an option for the wm8750 something like 'CONFIG_SND_SOC_IMX_CCWMX51_WM8750=y' but that option does not exist. I am assuming this is something that I would have to instantiate myself?
Not that familiar with Linux config files. As I understand them there is usually some mapping between the parameter and it's value that is used to select files as part of a "make" process. Not sure how you would go about adapting that mechanism, especially for files that don't exist or may not be readily available.
 

Thread Starter

Robert Murch

Joined Nov 2, 2015
43
@Papabravo Unfortunately, neither am I. Well, I appreciate your help thus fare. I went ahead and shot an email out to the author of that file so hopefully that bares some fruit.
 

nsaspook

Joined Aug 27, 2009
8,531
Last edited:

Thread Starter

Robert Murch

Joined Nov 2, 2015
43
@nsaspook So I just don't have a machine driver then? Could the old machine driver be adapted? What the hell is a machine driver and where is it located? This hardware stuff is more confusing than I thought it would be.

EDIT: Thanks btw nsaspook for taking the time. What confuses me is the difference between a machine driver and the codec driver itself.
 
Last edited:

Papabravo

Joined Feb 24, 2006
16,512
@nsaspook So I just don't have a machine driver then? Could the old machine driver be adapted? What the hell is a machine driver and where is it located? This hardware stuff is more confusing than I thought it would be.
We don't know what you have and don't have. The availability of source files (.c), and header files (.h) suggests that you have what you need. If you dont have the result of building object files from those source files you may need to do that. the result of that build process then needs to be located in a place where the software that builds a custom system can find it.

WRT to terminology. "Machine Driver" is not significantly different from "Driver" IMHO. A "Driver" is any piece of software that maps a generic set of OS calls onto a particular hardware device and returns information from the device back to the OS. I think you have what you need, but just don't know how to integrate it yet. For the ESS 9018 DAC it took almost 3 months to write the code from scratch to handle the device, and it was about 2000 lines of c-code. These devices are complicated but they present a regular structure for controlling and sometimes monitoring such devices.

The next step for you is to figure out what pieces are used in the construction of the "machine driver" for the WM8753. By analogy you should be able to use those source files to figure out what a "machine driver" for the WM8750 should look like.
 

Thread Starter

Robert Murch

Joined Nov 2, 2015
43
@Papabravo Sure, I understand please pardon my frustration as I too am not aware of what I have or do not have; nor am I aware of how to integrate what I have, if I do in fact have what I need; I do greatly appreciate any help. As I stated before I have about 4 months worth of experience with Linux systems which (in this scenario) amounts to about 0.
 
Last edited:

Papabravo

Joined Feb 24, 2006
16,512
@Papabravo Sure, I understand please pardon my frustration as I too am not aware of what I have or do not have; nor am I aware of how to integrate what I have, if I do in fact have what I need; I do greatly appreciate any help. As I stated before I have about 4 months worth of experience with Linux systems which (in this scenario) amounts to about 0.
I feel your pain. This is what the experienced engineers refer to as trial by fire. The first time you go through it will be by far the worst. Your immediate goal should be to make incremental progress BAMN.
 

Thread Starter

Robert Murch

Joined Nov 2, 2015
43
@nsaspook Do you think you could explain what it was you did in your last post? You mentioned: "GUI kernel xconfig utility 4.x kernel" is this a utility that I can run with a command from within the kernel directory?
 

nsaspook

Joined Aug 27, 2009
8,531
@nsaspook So I just don't have a machine driver then? Could the old machine driver be adapted? What the hell is a machine driver and where is it located? This hardware stuff is more confusing than I thought it would be.

EDIT: Thanks btw nsaspook for taking the time. What confuses me is the difference between a machine driver and the codec driver itself.
It's a board specific driver for the hardware abstraction.
For newer kernels.
https://www.kernel.org/doc/html/v4.16/sound/soc/machine.html
https://www.kernel.org/doc/html/v4.16/sound/soc/index.html
To achieve all this, ASoC basically splits an embedded audio system into multiple re-usable component drivers :-

  • Codec class drivers: The codec class driver is platform independent and contains audio controls, audio interface capabilities, codec DAPM definition and codec IO functions. This class extends to BT, FM and MODEM ICs if required. Codec class drivers should be generic code that can run on any architecture and machine.
  • Platform class drivers: The platform class driver includes the audio DMA engine driver, digital audio interface (DAI) drivers (e.g. I2S, AC97, PCM) and any audio DSP drivers for that platform.
  • Machine class driver: The machine driver class acts as the glue that describes and binds the other component drivers together to form an ALSA “sound card device”. It handles any machine specific controls and machine level audio events (e.g. turning on an amp at start of playback).

A short kernel HOWTO
http://www.berkes.ca/guides/linux_kernel.html

xconfig is just a xwindows based menu program for config options.
http://newbiedoc.sourceforge.net/tutorials/kernel-pkg/config-kernel-pkg.html.en
 
Last edited:

Thread Starter

Robert Murch

Joined Nov 2, 2015
43
@nsaspook Okay first off thank you for taking the time to post this information. I have a few questions if you dont mind:

1) Were you suggesting that I first try to enable the Build all ASoC CODEC drivers option? I could give that a shot if you think there is a chance.
2) I will read through all these links and information you have posted but just based on skimming it would seem that I could in fact alter the machine driver correct? I am assuming somewhere in there it will tell me where to go look for the machine driver.

EDIT: I didn't read the help menu correctly. Even if I enable the ASoC codec if the machine driver isn't setup to communicate with it then it won't work. Okay, I am beginning to understand what the machine driver is. So please ignore the first question.
 
Top