Linux Kernel  3.7.1
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
fsl_utils.c
Go to the documentation of this file.
1 
13 #include <linux/module.h>
14 #include <linux/of_address.h>
15 #include <sound/soc.h>
16 
17 #include "fsl_utils.h"
18 
32  const char *name,
33  struct snd_soc_dai_link *dai,
34  unsigned int *dma_channel_id,
35  unsigned int *dma_id)
36 {
37  struct resource res;
38  struct device_node *dma_channel_np, *dma_np;
39  const u32 *iprop;
40  int ret;
41 
42  dma_channel_np = of_parse_phandle(ssi_np, name, 0);
43  if (!dma_channel_np)
44  return -EINVAL;
45 
46  if (!of_device_is_compatible(dma_channel_np, "fsl,ssi-dma-channel")) {
47  of_node_put(dma_channel_np);
48  return -EINVAL;
49  }
50 
51  /* Determine the dev_name for the device_node. This code mimics the
52  * behavior of of_device_make_bus_id(). We need this because ASoC uses
53  * the dev_name() of the device to match the platform (DMA) device with
54  * the CPU (SSI) device. It's all ugly and hackish, but it works (for
55  * now).
56  *
57  * dai->platform name should already point to an allocated buffer.
58  */
59  ret = of_address_to_resource(dma_channel_np, 0, &res);
60  if (ret) {
61  of_node_put(dma_channel_np);
62  return ret;
63  }
64  snprintf((char *)dai->platform_name, DAI_NAME_SIZE, "%llx.%s",
65  (unsigned long long) res.start, dma_channel_np->name);
66 
67  iprop = of_get_property(dma_channel_np, "cell-index", NULL);
68  if (!iprop) {
69  of_node_put(dma_channel_np);
70  return -EINVAL;
71  }
72  *dma_channel_id = be32_to_cpup(iprop);
73 
74  dma_np = of_get_parent(dma_channel_np);
75  iprop = of_get_property(dma_np, "cell-index", NULL);
76  if (!iprop) {
77  of_node_put(dma_np);
78  return -EINVAL;
79  }
80  *dma_id = be32_to_cpup(iprop);
81 
82  of_node_put(dma_np);
83  of_node_put(dma_channel_np);
84 
85  return 0;
86 }
88 
89 MODULE_AUTHOR("Timur Tabi <[email protected]>");
90 MODULE_DESCRIPTION("Freescale ASoC utility code");
91 MODULE_LICENSE("GPL v2");