Path: blob/main/sys/contrib/dev/broadcom/brcm80211/brcmfmac/of.c
178665 views
// SPDX-License-Identifier: ISC1/*2* Copyright (c) 2014 Broadcom Corporation3*/4#include <linux/init.h>5#include <linux/of.h>6#include <linux/of_irq.h>7#include <linux/of_net.h>8#include <linux/clk.h>910#include <defs.h>11#include "debug.h"12#include "core.h"13#include "common.h"14#include "of.h"1516static int brcmf_of_get_country_codes(struct device *dev,17struct brcmf_mp_device *settings)18{19struct device_node *np = dev->of_node;20struct brcmfmac_pd_cc_entry *cce;21struct brcmfmac_pd_cc *cc;22int count;23int i;2425count = of_property_count_strings(np, "brcm,ccode-map");26if (count < 0) {27/* If no explicit country code map is specified, check whether28* the trivial map should be used.29*/30settings->trivial_ccode_map =31of_property_read_bool(np, "brcm,ccode-map-trivial");3233/* The property is optional, so return success if it doesn't34* exist. Otherwise propagate the error code.35*/36return (count == -EINVAL) ? 0 : count;37}3839cc = devm_kzalloc(dev, struct_size(cc, table, count), GFP_KERNEL);40if (!cc)41return -ENOMEM;4243cc->table_size = count;4445for (i = 0; i < count; i++) {46const char *map;4748cce = &cc->table[i];4950if (of_property_read_string_index(np, "brcm,ccode-map",51i, &map))52continue;5354/* String format e.g. US-Q2-86 */55if (sscanf(map, "%2c-%2c-%d", cce->iso3166, cce->cc,56&cce->rev) != 3)57brcmf_err("failed to read country map %s\n", map);58else59brcmf_dbg(INFO, "%s-%s-%d\n", cce->iso3166, cce->cc,60cce->rev);61}6263settings->country_codes = cc;6465return 0;66}6768int brcmf_of_probe(struct device *dev, enum brcmf_bus_type bus_type,69struct brcmf_mp_device *settings)70{71struct brcmfmac_sdio_pd *sdio = &settings->bus.sdio;72struct device_node *root, *np = dev->of_node;73struct of_phandle_args oirq;74struct clk *clk;75const char *prop;76int irq;77int err;78u32 irqf;79u32 val;8081/* Apple ARM64 platforms have their own idea of board type, passed in82* via the device tree. They also have an antenna SKU parameter83*/84err = of_property_read_string(np, "brcm,board-type", &prop);85if (!err)86settings->board_type = prop;8788if (!of_property_read_string(np, "apple,antenna-sku", &prop))89settings->antenna_sku = prop;9091/* The WLAN calibration blob is normally stored in SROM, but Apple92* ARM64 platforms pass it via the DT instead.93*/94prop = of_get_property(np, "brcm,cal-blob", &settings->cal_size);95if (prop && settings->cal_size)96settings->cal_blob = prop;9798/* Set board-type to the first string of the machine compatible prop */99root = of_find_node_by_path("/");100if (root && err) {101char *board_type = NULL;102const char *tmp;103104/* get rid of '/' in the compatible string to be able to find the FW */105if (!of_property_read_string_index(root, "compatible", 0, &tmp))106board_type = devm_kstrdup(dev, tmp, GFP_KERNEL);107108if (!board_type) {109of_node_put(root);110return 0;111}112strreplace(board_type, '/', '-');113settings->board_type = board_type;114}115of_node_put(root);116117clk = devm_clk_get_optional_enabled_with_rate(dev, "lpo", 32768);118if (IS_ERR(clk))119return PTR_ERR(clk);120121brcmf_dbg(INFO, "%s LPO clock\n", clk ? "enable" : "no");122123if (!np || !of_device_is_compatible(np, "brcm,bcm4329-fmac"))124return 0;125126err = brcmf_of_get_country_codes(dev, settings);127if (err)128brcmf_err("failed to get OF country code map (err=%d)\n", err);129130of_get_mac_address(np, settings->mac);131132if (bus_type != BRCMF_BUSTYPE_SDIO)133return 0;134135if (of_property_read_u32(np, "brcm,drive-strength", &val) == 0)136sdio->drive_strength = val;137138/* make sure there are interrupts defined in the node */139if (of_irq_parse_one(np, 0, &oirq))140return 0;141142irq = irq_create_of_mapping(&oirq);143if (!irq) {144brcmf_err("interrupt could not be mapped\n");145return 0;146}147irqf = irq_get_trigger_type(irq);148149sdio->oob_irq_supported = true;150sdio->oob_irq_nr = irq;151sdio->oob_irq_flags = irqf;152153return 0;154}155156157