summaryrefslogtreecommitdiffstats
path: root/include/sound/sof.h
blob: 4640566b54fe905d99761a3b1e6130c9932f0cfa (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
/* SPDX-License-Identifier: (GPL-2.0 OR BSD-3-Clause) */
/*
 * This file is provided under a dual BSD/GPLv2 license.  When using or
 * redistributing this file, you may do so under either license.
 *
 * Copyright(c) 2018 Intel Corporation. All rights reserved.
 *
 * Author: Liam Girdwood <liam.r.girdwood@linux.intel.com>
 */

#ifndef __INCLUDE_SOUND_SOF_H
#define __INCLUDE_SOUND_SOF_H

#include <linux/pci.h>
#include <sound/soc.h>
#include <sound/soc-acpi.h>

struct snd_sof_dsp_ops;

/*
 * SOF Platform data.
 */
struct snd_sof_pdata {
	const struct firmware *fw;
	const char *drv_name;
	const char *name;
	const char *platform;

	struct device *dev;

	/*
	 * notification callback used if the hardware initialization
	 * can take time or is handled in a workqueue. This callback
	 * can be used by the caller to e.g. enable runtime_pm
	 * or limit functionality until all low-level inits are
	 * complete.
	 */
	void (*sof_probe_complete)(struct device *dev);

	/* descriptor */
	const struct sof_dev_desc *desc;

	/* firmware and topology filenames */
	const char *fw_filename_prefix;
	const char *fw_filename;
	const char *tplg_filename_prefix;
	const char *tplg_filename;

	/* machine */
	struct platform_device *pdev_mach;
	const struct snd_soc_acpi_mach *machine;

	void *hw_pdata;
};

/*
 * Descriptor used for setting up SOF platform data. This is used when
 * ACPI/PCI data is missing or mapped differently.
 */
struct sof_dev_desc {
	/* list of machines using this configuration */
	struct snd_soc_acpi_mach *machines;

	/* Platform resource indexes in BAR / ACPI resources. */
	/* Must set to -1 if not used - add new items to end */
	int resindex_lpe_base;
	int resindex_pcicfg_base;
	int resindex_imr_base;
	int irqindex_host_ipc;
	int resindex_dma_base;

	/* DMA only valid when resindex_dma_base != -1*/
	int dma_engine;
	int dma_size;

	/* IPC timeouts in ms */
	int ipc_timeout;
	int boot_timeout;

	/* chip information for dsp */
	const void *chip_info;

	/* defaults for no codec mode */
	const char *nocodec_fw_filename;
	const char *nocodec_tplg_filename;

	/* defaults paths for firmware and topology files */
	const char *default_fw_path;
	const char *default_tplg_path;

	const struct snd_sof_dsp_ops *ops;
	const struct sof_arch_ops *arch_ops;
};

int sof_nocodec_setup(struct device *dev,
		      struct snd_sof_pdata *sof_pdata,
		      struct snd_soc_acpi_mach *mach,
		      const struct sof_dev_desc *desc,
		      const struct snd_sof_dsp_ops *ops);
#endif
ass="n">i = 0; i < newargc; i++) free(newargv[i]); free(newargv); } /* * Incrementally [re]allocate newargv and keep it NULL-terminated. */ static int validate_argv(int argc) { static int size = 0; if (argc >= size) { char **ptr; while (argc >= size) size += 64; ptr = realloc(newargv, size * sizeof(newargv[0])); if (ptr == NULL) return 0; (newargv = ptr)[argc] = NULL; } else { newargv[argc] = NULL; } return 1; } static int process_glob(WCHAR *wstr, int wlen) { int i, slash, udlen; WCHAR saved_char; WIN32_FIND_DATAW data; HANDLE h; /* * Note that we support wildcard characters only in filename part * of the path, and not in directories. Windows users are used to * this, that's why recursive glob processing is not implemented. */ /* * Start by looking for last slash or backslash, ... */ for (slash = 0, i = 0; i < wlen; i++) if (wstr[i] == L'/' || wstr[i] == L'\\') slash = i + 1; /* * ... then look for asterisk or question mark in the file name. */ for (i = slash; i < wlen; i++) if (wstr[i] == L'*' || wstr[i] == L'?') break; if (i == wlen) return 0; /* definitely not a glob */ saved_char = wstr[wlen]; wstr[wlen] = L'\0'; h = FindFirstFileW(wstr, &data); wstr[wlen] = saved_char; if (h == INVALID_HANDLE_VALUE) return 0; /* not a valid glob, just pass... */ if (slash) udlen = WideCharToMultiByte(CP_UTF8, 0, wstr, slash, NULL, 0, NULL, NULL); else udlen = 0; do { int uflen; char *arg; /* * skip over . and .. */ if (data.cFileName[0] == L'.') { if ((data.cFileName[1] == L'\0') || (data.cFileName[1] == L'.' && data.cFileName[2] == L'\0')) continue; } if (!validate_argv(newargc + 1)) break; /* * -1 below means "scan for trailing '\0' *and* count it", * so that |uflen| covers even trailing '\0'. */ uflen = WideCharToMultiByte(CP_UTF8, 0, data.cFileName, -1, NULL, 0, NULL, NULL); arg = malloc(udlen + uflen); if (arg == NULL) break; if (udlen) WideCharToMultiByte(CP_UTF8, 0, wstr, slash, arg, udlen, NULL, NULL); WideCharToMultiByte(CP_UTF8, 0, data.cFileName, -1, arg + udlen, uflen, NULL, NULL); newargv[newargc++] = arg; } while (FindNextFileW(h, &data)); CloseHandle(h); return 1; } void win32_utf8argv(int *argc, char **argv[]) { const WCHAR *wcmdline; WCHAR *warg, *wend, *p; int wlen, ulen, valid = 1; char *arg; if (GetEnvironmentVariableW(L"OPENSSL_WIN32_UTF8", NULL, 0) == 0) return; newargc = 0; newargv = NULL; if (!validate_argv(newargc)) return; wcmdline = GetCommandLineW(); if (wcmdline == NULL) return; /* * make a copy of the command line, since we might have to modify it... */ wlen = wcslen(wcmdline); p = _alloca((wlen + 1) * sizeof(WCHAR)); wcscpy(p, wcmdline); while (*p != L'\0') { int in_quote = 0; if (*p == L' ' || *p == L'\t') { p++; /* skip over white spaces */ continue; } /* * Note: because we may need to fiddle with the number of backslashes, * the argument string is copied into itself. This is safe because * the number of characters will never expand. */ warg = wend = p; while (*p != L'\0' && (in_quote || (*p != L' ' && *p != L'\t'))) { switch (*p) { case L'\\': /* * Microsoft documentation on how backslashes are treated * is: * * + Backslashes are interpreted literally, unless they * immediately precede a double quotation mark. * + If an even number of backslashes is followed by a double * quotation mark, one backslash is placed in the argv array * for every pair of backslashes, and the double quotation * mark is interpreted as a string delimiter. * + If an odd number of backslashes is followed by a double * quotation mark, one backslash is placed in the argv array * for every pair of backslashes, and the double quotation * mark is "escaped" by the remaining backslash, causing a * literal double quotation mark (") to be placed in argv. * * Ref: https://msdn.microsoft.com/en-us/library/17w5ykft.aspx * * Though referred page doesn't mention it, multiple qouble * quotes are also special. Pair of double quotes in quoted * string is counted as single double quote. */ { const WCHAR *q = p; int i; while (*p == L'\\') p++; if (*p == L'"') { int i; for (i = (p - q) / 2; i > 0; i--) *wend++ = L'\\'; /* * if odd amount of backslashes before the quote, * said quote is part of the argument, not a delimiter */ if ((p - q) % 2 == 1) *wend++ = *p++; } else { for (i = p - q; i > 0; i--) *wend++ = L'\\'; } } break; case L'"': /* * Without the preceding backslash (or when preceded with an * even number of backslashes), the double quote is a simple * string delimiter and just slightly change the parsing state */ if (in_quote && p[1] == L'"') *wend++ = *p++; else in_quote = !in_quote; p++; break; default: /* * Any other non-delimiter character is just taken verbatim */ *wend++ = *p++; } } wlen = wend - warg; if (wlen == 0 || !process_glob(warg, wlen)) { if (!validate_argv(newargc + 1)) { valid = 0; break; } ulen = 0; if (wlen > 0) { ulen = WideCharToMultiByte(CP_UTF8, 0, warg, wlen, NULL, 0, NULL, NULL); if (ulen <= 0) continue; } arg = malloc(ulen + 1); if (arg == NULL) { valid = 0; break; } if (wlen > 0) WideCharToMultiByte(CP_UTF8, 0, warg, wlen, arg, ulen, NULL, NULL); arg[