0001
0002
0003
0004
0005 #include <linux/init.h>
0006 #include <linux/of.h>
0007 #include <linux/of_irq.h>
0008 #include <linux/of_net.h>
0009
0010 #include <defs.h>
0011 #include "debug.h"
0012 #include "core.h"
0013 #include "common.h"
0014 #include "of.h"
0015
0016 static int brcmf_of_get_country_codes(struct device *dev,
0017 struct brcmf_mp_device *settings)
0018 {
0019 struct device_node *np = dev->of_node;
0020 struct brcmfmac_pd_cc_entry *cce;
0021 struct brcmfmac_pd_cc *cc;
0022 int count;
0023 int i;
0024
0025 count = of_property_count_strings(np, "brcm,ccode-map");
0026 if (count < 0) {
0027
0028
0029
0030 settings->trivial_ccode_map =
0031 of_property_read_bool(np, "brcm,ccode-map-trivial");
0032
0033
0034
0035
0036 return (count == -EINVAL) ? 0 : count;
0037 }
0038
0039 cc = devm_kzalloc(dev, struct_size(cc, table, count), GFP_KERNEL);
0040 if (!cc)
0041 return -ENOMEM;
0042
0043 cc->table_size = count;
0044
0045 for (i = 0; i < count; i++) {
0046 const char *map;
0047
0048 cce = &cc->table[i];
0049
0050 if (of_property_read_string_index(np, "brcm,ccode-map",
0051 i, &map))
0052 continue;
0053
0054
0055 if (sscanf(map, "%2c-%2c-%d", cce->iso3166, cce->cc,
0056 &cce->rev) != 3)
0057 brcmf_err("failed to read country map %s\n", map);
0058 else
0059 brcmf_dbg(INFO, "%s-%s-%d\n", cce->iso3166, cce->cc,
0060 cce->rev);
0061 }
0062
0063 settings->country_codes = cc;
0064
0065 return 0;
0066 }
0067
0068 void brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,
0069 struct brcmf_mp_device *settings)
0070 {
0071 struct brcmfmac_sdio_pd *sdio = &settings->bus.sdio;
0072 struct device_node *root, *np = dev->of_node;
0073 int irq;
0074 int err;
0075 u32 irqf;
0076 u32 val;
0077
0078
0079 root = of_find_node_by_path("/");
0080 if (root) {
0081 char *board_type;
0082 const char *tmp;
0083
0084 of_property_read_string_index(root, "compatible", 0, &tmp);
0085
0086
0087 board_type = devm_kstrdup(dev, tmp, GFP_KERNEL);
0088 if (!board_type) {
0089 of_node_put(root);
0090 return;
0091 }
0092 strreplace(board_type, '/', '-');
0093 settings->board_type = board_type;
0094
0095 of_node_put(root);
0096 }
0097
0098 if (!np || !of_device_is_compatible(np, "brcm,bcm4329-fmac"))
0099 return;
0100
0101 err = brcmf_of_get_country_codes(dev, settings);
0102 if (err)
0103 brcmf_err("failed to get OF country code map (err=%d)\n", err);
0104
0105 of_get_mac_address(np, settings->mac);
0106
0107 if (bus_type != BRCMF_BUSTYPE_SDIO)
0108 return;
0109
0110 if (of_property_read_u32(np, "brcm,drive-strength", &val) == 0)
0111 sdio->drive_strength = val;
0112
0113
0114 if (!of_find_property(np, "interrupts", NULL))
0115 return;
0116
0117 irq = irq_of_parse_and_map(np, 0);
0118 if (!irq) {
0119 brcmf_err("interrupt could not be mapped\n");
0120 return;
0121 }
0122 irqf = irqd_get_trigger_type(irq_get_irq_data(irq));
0123
0124 sdio->oob_irq_supported = true;
0125 sdio->oob_irq_nr = irq;
0126 sdio->oob_irq_flags = irqf;
0127 }