/*
* Apple Onboard Audio driver -- layout fabric
*
* Copyright 2006 Johannes Berg <johannes@sipsolutions.net>
*
* GPL v2, can be found in COPYING.
*
*
* This fabric module looks for sound codecs
* based on the layout-id property in the device tree.
*
*/
#include <asm/prom.h>
#include <linux/list.h>
#include <linux/module.h>
#include "../aoa.h"
#include "../soundbus/soundbus.h"
MODULE_AUTHOR("Johannes Berg <johannes@sipsolutions.net>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Layout-ID fabric for snd-aoa");
#define MAX_CODECS_PER_BUS 2
/* These are the connections the layout fabric
* knows about. It doesn't really care about the
* input ones, but I thought I'd separate them
* to give them proper names. The thing is that
* Apple usually will distinguish the active output
* by GPIOs, while the active input is set directly
* on the codec. Hence we here tell the codec what
* we think is connected. This information is hard-
* coded below ... */
#define CC_SPEAKERS (1<<0)
#define CC_HEADPHONE (1<<1)
#define CC_LINEOUT (1<<2)
#define CC_DIGITALOUT (1<<3)
#define CC_LINEIN (1<<4)
#define CC_MICROPHONE (1<<5)
#define CC_DIGITALIN (1<<6)
/* pretty bogus but users complain...
* This is a flag saying that the LINEOUT
* should be renamed to HEADPHONE.
* be careful with input detection! */
#define CC_LINEOUT_LABELLED_HEADPHONE (1<<7)
struct codec_connection {
/* CC_ flags from above */
int connected;
/* codec dependent bit to be set in the aoa_codec.connected field.
* This intentionally doesn't have any generic flags because the
* fabric has to know the codec anyway and all codecs might have
* different connectors */
int codec_bit;
};
struct codec_connect_info {
char *name;
struct codec_connection *connections;
};
#define LAYOUT_FLAG_COMBO_LINEOUT_SPDIF (1<<0)
struct layout {
unsigned int layout_id;
struct codec_connect_info codecs[MAX_CODECS_PER_BUS];
int flags;
/* if busname is not assigned, we use 'Master' below,
* so that our layout table doesn't need to be filled
* too much.
* We only assign these two if we expect to find more
* than one soundbus, i.e. on those machines with
* multiple layout-ids */
char *busname;
int pcmid;
};
MODULE_ALIAS("sound-layout-36");
MODULE_ALIAS("sound-layout-41");
MODULE_ALIAS("sound-layout-45");
MODULE_ALIAS("sound-layout-47");
MODULE_ALIAS("sound-layout-48");
MODULE_ALIAS("sound-layout-49");
MODULE_ALIAS("sound-layout-50");
MODULE_ALIAS("sound-layout-51");
MODULE_ALIAS("sound-layout-56");
MODULE_ALIAS("sound-layout-57");
MODULE_ALIAS("sound-layout-58");
MODULE_ALIAS("sound-layout-60");
MODULE_ALIAS("sound-layout-61");
MODULE_ALIAS("sound-layout-62");
MODULE_ALIAS("sound-layout-64");
MODULE_ALIAS("sound-layout-65");
MODULE_ALIAS("sound-layout-66");
MODULE_ALIAS("sound-layout-67");
MODULE_ALIAS("sound-layout-68");
MODULE_ALIAS("sound-layout-69");
MODULE_ALIAS("sound-layout-70");
MODULE_ALIAS("sound-layout-72");
MODULE_ALIAS("sound-layout-76");
MODULE_ALIAS("sound-layout-80");
MODULE_ALIAS("sound-layout-82");
MODULE_ALIAS("sound-layout-84");
MODULE_ALIAS("sound-layout-86");
MODULE_ALIAS("sound-layout-90");
MODULE_ALIAS("sound-layout-92");
MODULE_ALIAS("sound-layout-94");
MODULE_ALIAS("sound-layout-96");
MODULE_ALIAS("sound-layout-98");
MODULE_ALIAS("sound-layout-100");
/* onyx with all but microphone connected */
static struct codec_connection onyx_connections_nomic[] = {
{
.connected = CC_SPEAKERS | CC_HEADPHONE | CC_LINEOUT,
.codec_bit = 0,
},
{
.connected = CC_DIGITALOUT,
.codec_bit = 1,
},
{
.connected = CC_LINEIN,
.codec_bit = 2,
},
{} /* terminate array by .connected == 0 */
};
/* onyx on machines without headphone */
static struct codec_connection onyx_connections_noheadphones[] = {
{
.connected = CC_SPEAKERS | CC_LINEOUT |
CC_LINEOUT_LABELLED_HEADPHONE,
.codec_bit = 0,
},
{
.connected = CC_DIGITALOUT,
.codec_bit = 1,
},
/* FIXME: are these correct? probably not for all the machines
* below ... If not this will need separating. */
{
.connected = CC_LINEIN,
.codec_bit = 2,
},
{
.connected = CC_MICROPHONE,
.codec_bit = 3,
},
{} /* terminate array by .connected == 0 */
};
/* onyx on machines with real line-out */
static struct codec_connection onyx_connections_reallineout[] = {
{
.connected = CC_SPEAKERS | CC_LINEOUT | CC_HEADPHONE,
.codec_bit = 0,
},
{
.connected = CC_DIGITALOUT,
.codec_bit = 1,
},
{
.connected = CC_LINEIN,
.codec_bit = 2,
},
{} /* terminate array by .connected == 0 */
};
/* tas on machines without line out */
static struct codec_connection tas_connections_nolineout[] = {
{
.connected =