2
* ALSA SoC OMAP ABE port manager
4
* Author: Liam Girdwood <lrg@slimlogic.co.uk>
6
* This program is free software; you can redistribute it and/or
7
* modify it under the terms of the GNU General Public License
8
* version 2 as published by the Free Software Foundation.
10
* This program is distributed in the hope that it will be useful, but
11
* WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
* General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
23
#include <linux/module.h>
24
#include <linux/init.h>
25
#include <linux/slab.h>
26
#include <linux/errno.h>
27
#include <linux/spinlock.h>
28
#include <linux/list.h>
29
#include <linux/debugfs.h>
30
#include <linux/device.h>
34
#ifdef CONFIG_DEBUG_FS
35
/* this must match logical ID numbers in port_mgr.h */
36
static const char *lport_name[] = {
37
"dmic0", "dmic1", "dmic2", "pdmdl1", "pdmdl2", "pdmvib",
38
"pdmul1", "bt_vx_dl", "bt_vx_ul", "mm_ext_ul", "mm_ext_dl",
39
"mm_dl1", "mm_ul1", "mm_ul2", "vx_dl", "vx_ul", "vib", "tones"
43
static DEFINE_MUTEX(port_mgr_mutex);
44
static struct abe *the_abe = NULL;
48
* Get the Physical port ID based on the logical port ID
50
* FE and BE ports have unique ID's within the driver but share
51
* ID's within the ABE. This maps a driver port ID to an ABE port ID.
53
static int get_physical_id(int logical_id)
57
case OMAP_ABE_BE_PORT_DMIC0:
58
case OMAP_ABE_BE_PORT_DMIC1:
59
case OMAP_ABE_BE_PORT_DMIC2:
61
case OMAP_ABE_BE_PORT_PDM_DL1:
62
case OMAP_ABE_BE_PORT_PDM_DL2:
64
case OMAP_ABE_BE_PORT_PDM_VIB:
66
case OMAP_ABE_BE_PORT_PDM_UL1:
68
case OMAP_ABE_BE_PORT_BT_VX_DL:
70
case OMAP_ABE_BE_PORT_BT_VX_UL:
72
case OMAP_ABE_BE_PORT_MM_EXT_UL:
73
return MM_EXT_OUT_PORT;
74
case OMAP_ABE_BE_PORT_MM_EXT_DL:
75
return MM_EXT_IN_PORT;
77
case OMAP_ABE_FE_PORT_MM_DL1:
79
case OMAP_ABE_FE_PORT_MM_UL1:
81
case OMAP_ABE_FE_PORT_MM_UL2:
83
case OMAP_ABE_FE_PORT_VX_DL:
85
case OMAP_ABE_FE_PORT_VX_UL:
87
case OMAP_ABE_FE_PORT_VIB:
89
case OMAP_ABE_FE_PORT_TONES:
96
* Get the number of enabled users of the physical port shared by this client.
97
* Locks held by callers.
99
static int port_get_num_users(struct abe *abe, struct omap_abe_port *port)
101
struct omap_abe_port *p;
104
list_for_each_entry(p, &abe->ports, list) {
105
if (p->physical_id == port->physical_id && p->state == PORT_ENABLED)
111
static int port_is_open(struct abe *abe, int phy_port)
113
struct omap_abe_port *p;
115
list_for_each_entry(p, &abe->ports, list) {
116
if (p->physical_id == phy_port && p->state == PORT_ENABLED)
123
* Check whether the physical port is enabled for this PHY port ID.
124
* Locks held by callers.
126
int omap_abe_port_is_enabled(struct abe *abe, struct omap_abe_port *port)
128
struct omap_abe_port *p;
131
spin_lock_irqsave(&abe->lock, flags);
133
list_for_each_entry(p, &abe->ports, list) {
134
if (p->physical_id == port->physical_id && p->state == PORT_ENABLED) {
135
spin_unlock_irqrestore(&abe->lock, flags);
140
spin_unlock_irqrestore(&abe->lock, flags);
143
EXPORT_SYMBOL(omap_abe_port_is_enabled);
146
* omap_abe_port_enable - enable ABE logical port
149
* @port - logical ABE port ID to be enabled.
151
int omap_abe_port_enable(struct abe *abe, struct omap_abe_port *port)
156
/* only enable the physical port iff it is disabled */
157
pr_debug("port %s increment count %d\n",
158
lport_name[port->logical_id], port->users);
160
spin_lock_irqsave(&abe->lock, flags);
161
if (port->users == 0 && port_get_num_users(abe, port) == 0) {
163
/* enable the physical port */
164
pr_debug("port %s phy port %d enabled\n",
165
lport_name[port->logical_id], port->physical_id);
166
abe_enable_data_transfer(port->physical_id);
169
port->state = PORT_ENABLED;
171
spin_unlock_irqrestore(&abe->lock, flags);
174
EXPORT_SYMBOL(omap_abe_port_enable);
177
* omap_abe_port_disable - disable ABE logical port
180
* @port - logical ABE port ID to be disabled.
182
int omap_abe_port_disable(struct abe *abe, struct omap_abe_port *port)
187
/* only disable the port iff no other users are using it */
188
pr_debug("port %s decrement count %d\n",
189
lport_name[port->logical_id], port->users);
191
spin_lock_irqsave(&abe->lock, flags);
192
if (port->users == 1 && port_get_num_users(abe, port) == 1) {
193
/* disable the physical port */
194
pr_debug("port %s phy port %d disabled\n",
195
lport_name[port->logical_id], port->physical_id);
197
abe_disable_data_transfer(port->physical_id);
200
port->state = PORT_DISABLED;
202
spin_unlock_irqrestore(&abe->lock, flags);
205
EXPORT_SYMBOL(omap_abe_port_disable);
208
* omap_abe_port_open - open ABE logical port
211
* @logical_id - logical ABE port ID to be opened.
213
struct omap_abe_port *omap_abe_port_open(struct abe *abe, int logical_id)
215
struct omap_abe_port *port;
218
#ifdef CONFIG_DEBUG_FS
219
char debug_fs_name[32];
222
if (logical_id < 0 || logical_id > OMAP_ABE_MAX_PORT_ID)
225
if (port_is_open(abe, logical_id))
228
port = kzalloc(sizeof(struct omap_abe_port), GFP_KERNEL);
232
port->logical_id = logical_id;
233
port->physical_id = get_physical_id(logical_id);
234
port->state = PORT_DISABLED;
237
spin_lock_irqsave(&abe->lock, flags);
238
list_add(&port->list, &abe->ports);
239
spin_unlock_irqrestore(&abe->lock, flags);
240
port->physical_users = port_get_num_users(abe, port);
242
#ifdef CONFIG_DEBUG_FS
243
sprintf(debug_fs_name, "%s_state", lport_name[logical_id]);
244
port->debugfs_lstate = debugfs_create_u32(debug_fs_name, 0644,
245
abe->debugfs_root, &port->state);
246
sprintf(debug_fs_name, "%s_phy", lport_name[logical_id]);
247
port->debugfs_lphy = debugfs_create_u32(debug_fs_name, 0644,
248
abe->debugfs_root, &port->physical_id);
249
sprintf(debug_fs_name, "%s_users", lport_name[logical_id]);
250
port->debugfs_lusers = debugfs_create_u32(debug_fs_name, 0644,
251
abe->debugfs_root, &port->users);
254
pr_debug("opened port %s\n", lport_name[logical_id]);
257
EXPORT_SYMBOL(omap_abe_port_open);
260
* omap_abe_port_close - close ABE logical port
262
* @port - logical ABE port to be closed (and disabled).
264
void omap_abe_port_close(struct abe *abe, struct omap_abe_port *port)
268
/* disable the port */
269
omap_abe_port_disable(abe, port);
271
spin_lock_irqsave(&abe->lock, flags);
272
list_del(&port->list);
273
spin_unlock_irqrestore(&abe->lock, flags);
275
pr_debug("closed port %s\n", lport_name[port->logical_id]);
278
EXPORT_SYMBOL(omap_abe_port_close);
280
static struct abe *omap_abe_port_mgr_init(void)
284
abe = kzalloc(sizeof(struct abe), GFP_KERNEL);
288
spin_lock_init(&abe->lock);
290
INIT_LIST_HEAD(&abe->ports);
293
#ifdef CONFIG_DEBUG_FS
294
abe->debugfs_root = debugfs_create_dir("abe_port", NULL);
295
if (!abe->debugfs_root) {
296
pr_debug( "Failed to create port manager debugfs directory\n");
302
static void omap_abe_port_mgr_free(struct abe *abe)
304
debugfs_remove_recursive(abe->debugfs_root);
309
struct abe *omap_abe_port_mgr_get(void)
313
mutex_lock(&port_mgr_mutex);
318
abe = omap_abe_port_mgr_init();
321
mutex_unlock(&port_mgr_mutex);
324
EXPORT_SYMBOL(omap_abe_port_mgr_get);
326
void omap_abe_port_mgr_put(struct abe *abe)
328
mutex_lock(&port_mgr_mutex);
334
omap_abe_port_mgr_free(abe);
337
mutex_unlock(&port_mgr_mutex);
339
EXPORT_SYMBOL(omap_abe_port_mgr_put);
341
MODULE_LICENSE("GPL");