From patchwork Wed Jan 31 22:37:25 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Linus Walleij X-Patchwork-Id: 195004 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a05:693c:2685:b0:106:209c:c626 with SMTP id mn5csp68045dyc; Wed, 31 Jan 2024 14:40:50 -0800 (PST) X-Google-Smtp-Source: AGHT+IFFbKth+JpmhYVtXP+u2vipSP+NfTAmVUB9eK5mu7til1Q5EjKUuiWHRfKNTg7k1NyMhUjO X-Received: by 2002:a17:90a:43e2:b0:290:146b:ed81 with SMTP id r89-20020a17090a43e200b00290146bed81mr3256904pjg.8.1706740849926; Wed, 31 Jan 2024 14:40:49 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1706740849; cv=pass; d=google.com; s=arc-20160816; b=aTsGsoM4bi/18Pmp3S6u39Jajt3CMk4rviav3k2uttA7fzjbp/juCliJDlRRJu8U+W E1eA0DQxZZo4/eBdxrg485Crgs5vP9FfA4NgGrMQek3eVvDDp3lITCJyh7ZBcqlu0LRE HKNzm0vyxdf3dGueRk1iq1CDHBqKifud5YfKg3LL8SsE2ZxsMYn2mE2aS/5l3vCgYzaN YzPrMt9Cu7UEfyvo+nJjt81mvmV7MxZJ6E2DtYJvlP0WnTv9b0p2IqqO9oFSJUWrf42e iVZdgQi68CBZ33kjeTHFe8a0rGqKJoSR4de0oAf9ulTNn66GrbEXfpZIe8sSG1tsFm3I tijA== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:list-unsubscribe:list-subscribe:list-id:precedence :subject:date:from:dkim-signature; bh=okzddJtDl2wZ92vdZoXz+eQZ4Yo4IwWgeQb2Nkz5V54=; fh=ufn5Wul3oG6eQdaQJ7MtzUo9Zb3YgopFubPeNMawuAM=; b=Mrjv73l0C5ifo5kt+YSmaRZ3fY2DSgJbL74GY1eGgb/NbdpqNlua7criENuuYgRdtd TcP3xnDBQf5euJLyPHo/Xe37WEs+oH/dEnzHtjPykRAvUe/S1VykDTpeLehfmUVl9iXO 316xfPldZ7GCOD5qHS57OMgZj+jlH8gscREAHi8FNZ49vtjTVLi3MkMlRcrgQK9ocLRf NKZco0Zf6M3HrQMH5XgJ4kdW8CSs/lrmokf9eORWmGoMMhxbSU8SsuJGng1riboo+EHH XcWULNQ3SVnrSUygnKpKI0yCb/0bOz5iemLCbkt4c2gBUvltFVsT1QO+FUBEO8IuIICv G+KQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=aBhqhn4j; arc=pass (i=1 spf=pass spfdomain=linaro.org dkim=pass dkdomain=linaro.org dmarc=pass fromdomain=linaro.org); spf=pass (google.com: domain of linux-kernel+bounces-47267-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-47267-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org X-Forwarded-Encrypted: i=1; AJvYcCVBnBca6t6VNEiLQJcOju19hBLeIvHVm5jfeXbuRTHBt0NImEQgNxNo2OmVdU/QwlOchOzbbDE53Y/3UbUMsrUAkg4pqg== Received: from sv.mirrors.kernel.org (sv.mirrors.kernel.org. [2604:1380:45e3:2400::1]) by mx.google.com with ESMTPS id ga22-20020a17090b039600b00295dcfeb4afsi2206162pjb.2.2024.01.31.14.40.49 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 31 Jan 2024 14:40:49 -0800 (PST) Received-SPF: pass (google.com: domain of linux-kernel+bounces-47267-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) client-ip=2604:1380:45e3:2400::1; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=aBhqhn4j; arc=pass (i=1 spf=pass spfdomain=linaro.org dkim=pass dkdomain=linaro.org dmarc=pass fromdomain=linaro.org); spf=pass (google.com: domain of linux-kernel+bounces-47267-ouuuleilei=gmail.com@vger.kernel.org designates 2604:1380:45e3:2400::1 as permitted sender) smtp.mailfrom="linux-kernel+bounces-47267-ouuuleilei=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sv.mirrors.kernel.org (Postfix) with ESMTPS id A2B382924E0 for ; Wed, 31 Jan 2024 22:39:22 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 7571C3A8D2; Wed, 31 Jan 2024 22:37:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b="aBhqhn4j" Received: from mail-lf1-f52.google.com (mail-lf1-f52.google.com [209.85.167.52]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C94043B29A for ; Wed, 31 Jan 2024 22:37:33 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.167.52 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706740656; cv=none; b=KOhDYl/Bzk0qurce9PwMd7q0QvO6zVp4tdWXcdGOtDj5D5nLuTYd/xgdYLb8SwGFWpE89KBLQt6fAbj6ym7h6DcxpSMxdlhfTFNbWFIzkL/2j18L7lsl34qQ6P3OpHCLM3ho6yiU2i/tjdruZNdMb3WxbSXstqhCQWOaHL+yLWk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1706740656; c=relaxed/simple; bh=WvEjD8jcit9p/EBjrR1N6NawFgsZhp6NvZZ3ZQiGnQs=; h=From:Date:Subject:MIME-Version:Content-Type:Message-Id:References: In-Reply-To:To:Cc; b=f6ROl58LQJbZP/kBK3jgvGkmSJC8STrp9W9+wKntJHtQvqyK9qSznHQnZhA6jrN3iXnvdabf9GtYfSa9JfeO/v6NuvwrD3EJcxoqunXBaQ6wgDjSl6WTZCXGUeQMQcCtyrTk8sacX1hhk1KjhWcAIIA7qnAx5blX9P88IBcjtpc= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org; spf=pass smtp.mailfrom=linaro.org; dkim=pass (2048-bit key) header.d=linaro.org header.i=@linaro.org header.b=aBhqhn4j; arc=none smtp.client-ip=209.85.167.52 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=linaro.org Received: by mail-lf1-f52.google.com with SMTP id 2adb3069b0e04-51124e08565so448130e87.3 for ; Wed, 31 Jan 2024 14:37:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1706740652; x=1707345452; darn=vger.kernel.org; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:from:to:cc:subject:date:message-id :reply-to; bh=okzddJtDl2wZ92vdZoXz+eQZ4Yo4IwWgeQb2Nkz5V54=; b=aBhqhn4jpqKVsL42Zp9armYhYRFNPAKOL2ufm6CGUzf9KNynM7FSlLgUudv2Bmch5/ ArugxE8+TRa05dVM6JoKuDq83PYn/RPJNFDLdbR+XqVqJ/TXvsW89+tGpkw4Mlobwj+A uL6+WXcl8wn1hVZTEDRezstVFFttL0AmCOfXItDGvOuBgpIH/jzKphwan99TnMqa+03p ugng4cv1CNCY+ze9NLrxPIFGMYtsxD4Mg1QnnJookpddW2HMZyJABn0+Eda/x9dzgxzG 0R2oQpC3S1kBdc13KPEE8sKZ61oiL1kfVXf4tkSlk3ZMNEr9QVNZtxEq4GfVS1uwppc/ saWw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1706740652; x=1707345452; h=cc:to:in-reply-to:references:message-id:content-transfer-encoding :mime-version:subject:date:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=okzddJtDl2wZ92vdZoXz+eQZ4Yo4IwWgeQb2Nkz5V54=; b=JklKR9csx1glPjZAi3moQvN2JBMvU1M7i+MBpolPqPCaAyC723/bt39lrTFDCiet30 ewThfO036wEUyHDa/7EMkFOyK6opuKwgGYOo5HgPHaaMA/p73Ek9g3o1KazR2/TzYVlW MW/hT7moNmK6c2SZf2InHEvE8dB+71zMS/+QpuVl5Z+oWdqWNq/glezXFY82xNGuF02J F313wjV50MCBfzG5JMT3DxZti7i2bnse+gvfA7yJlgO2GL5qVb7GKAxobUmBXYUzfMeQ tXeQzQNYoK/PzmpZfXYLhKQJCIWBcNhdiG8HQsDDUcxp1TR8/G6fJmJ+c9nuOQSJLkEG zoiQ== X-Gm-Message-State: AOJu0YxcdiNfWYrMIk3400lCBC4CijYWctsCtTKVXOuSTT6pgd34ObO1 zjfO48yEByVcYLn5GCAjvKFt1sAsyySJXreEYZDowPL1HHoGgNl0pvYtyfFkQlc= X-Received: by 2002:a05:6512:4db:b0:511:211b:43e0 with SMTP id w27-20020a05651204db00b00511211b43e0mr607338lfq.67.1706740651893; Wed, 31 Jan 2024 14:37:31 -0800 (PST) X-Forwarded-Encrypted: i=0; AJvYcCVmMjpi/JZHvgCPf0wWOUcgxhE44ZJ1CcrefxPHn3urkFqe8PyCMR2Ap73e1z7vbcWYclVFMIwn6t/jRE0miJi/wOngtnIiuy17U+6HTtTIPJyiDTB3FrdpEfhTCCZ8MSyL0M0+KO5ZLfo02uzSy6kyxqouDICtztL4lQtL+eSvLKZVUDYwjq9QJ/ni8VJEfSJTBgwG3DPoZSipr2zFbie9GXaNMHvou8x1aGcpIjr+hVt6nZRisYSM37W0CvNQd5y11I84WJAVglqnbFttCIyTHCWaxI36Pd3CFqsrJJRTOW63Hxy6cf4AA6VOSCK3eA/dC68tGvDVKbE1KKAzRzsylgHnVxQD/6i4d75wIwhWb/AaqLbLnqh2wf2WbEL2OBGXQDBTujPoGLRWTQhow214dH9W6M1qngNCQRjFjUSG8zOryilrr2nYqStsjEFxr6ZpDw7uUAln9Tmbig== Received: from [127.0.1.1] ([85.235.12.238]) by smtp.gmail.com with ESMTPSA id v25-20020a05651203b900b0051023149df3sm1976021lfp.248.2024.01.31.14.37.30 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 31 Jan 2024 14:37:31 -0800 (PST) From: Linus Walleij Date: Wed, 31 Jan 2024 23:37:25 +0100 Subject: [PATCH 6/6] wifi: cw1200: Convert to GPIO descriptors Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Message-Id: <20240131-descriptors-wireless-v1-6-e1c7c5d68746@linaro.org> References: <20240131-descriptors-wireless-v1-0-e1c7c5d68746@linaro.org> In-Reply-To: <20240131-descriptors-wireless-v1-0-e1c7c5d68746@linaro.org> To: =?utf-8?q?Toke_H=C3=B8iland-J=C3=B8rgensen?= , Kalle Valo , Arend van Spriel , Franky Lin , Hante Meuleman , Andy Shevchenko , Arnd Bergmann , Lee Jones , Brian Norris , Srinivasan Raju Cc: linux-wireless@vger.kernel.org, linux-kernel@vger.kernel.org, brcm80211-dev-list.pdl@broadcom.com, Linus Walleij X-Mailer: b4 0.12.4 X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1789647493568808929 X-GMAIL-MSGID: 1789647493568808929 The CW1200 uses two GPIOs to control the powerup and reset pins, get these from GPIO descriptors instead of being passed as platform data from boardfiles. The RESET line will need to be marked as active low as we will let gpiolib handle the polarity inversion. The SDIO case is a bit special since the "card" need to be powered up before it gets detected on the SDIO bus and properly probed. Fix this by using board-specific GPIOs assigned to device "NULL". There are currently no in-tree users. Signed-off-by: Linus Walleij --- drivers/net/wireless/st/cw1200/cw1200_sdio.c | 42 +++++++++------- drivers/net/wireless/st/cw1200/cw1200_spi.c | 71 ++++++++++++++++------------ include/linux/platform_data/net-cw1200.h | 4 -- 3 files changed, 65 insertions(+), 52 deletions(-) diff --git a/drivers/net/wireless/st/cw1200/cw1200_sdio.c b/drivers/net/wireless/st/cw1200/cw1200_sdio.c index 4c30b5772ce0..00c4731d8f8e 100644 --- a/drivers/net/wireless/st/cw1200/cw1200_sdio.c +++ b/drivers/net/wireless/st/cw1200/cw1200_sdio.c @@ -8,7 +8,7 @@ #include #include -#include +#include #include #include #include @@ -178,12 +178,15 @@ static int cw1200_sdio_irq_unsubscribe(struct hwbus_priv *self) return ret; } +/* Like the rest of the driver, this only supports one device per system */ +static struct gpio_desc *cw1200_reset; +static struct gpio_desc *cw1200_powerup; + static int cw1200_sdio_off(const struct cw1200_platform_data_sdio *pdata) { - if (pdata->reset) { - gpio_set_value(pdata->reset, 0); + if (cw1200_reset) { + gpiod_set_value(cw1200_reset, 0); msleep(30); /* Min is 2 * CLK32K cycles */ - gpio_free(pdata->reset); } if (pdata->power_ctrl) @@ -196,16 +199,21 @@ static int cw1200_sdio_off(const struct cw1200_platform_data_sdio *pdata) static int cw1200_sdio_on(const struct cw1200_platform_data_sdio *pdata) { - /* Ensure I/Os are pulled low */ - if (pdata->reset) { - gpio_request(pdata->reset, "cw1200_wlan_reset"); - gpio_direction_output(pdata->reset, 0); + /* Ensure I/Os are pulled low (reset is active low) */ + cw1200_reset = devm_gpiod_get_optional(NULL, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(cw1200_reset)) { + pr_err("could not get CW1200 SDIO reset GPIO\n"); + return PTR_ERR(cw1200_reset); } - if (pdata->powerup) { - gpio_request(pdata->powerup, "cw1200_wlan_powerup"); - gpio_direction_output(pdata->powerup, 0); + gpiod_set_consumer_name(cw1200_reset, "cw1200_wlan_reset"); + cw1200_powerup = devm_gpiod_get_optional(NULL, "powerup", GPIOD_OUT_LOW); + if (IS_ERR(cw1200_powerup)) { + pr_err("could not get CW1200 SDIO powerup GPIO\n"); + return PTR_ERR(cw1200_powerup); } - if (pdata->reset || pdata->powerup) + gpiod_set_consumer_name(cw1200_powerup, "cw1200_wlan_powerup"); + + if (cw1200_reset || cw1200_powerup) msleep(10); /* Settle time? */ /* Enable 3v3 and 1v8 to hardware */ @@ -226,13 +234,13 @@ static int cw1200_sdio_on(const struct cw1200_platform_data_sdio *pdata) } /* Enable POWERUP signal */ - if (pdata->powerup) { - gpio_set_value(pdata->powerup, 1); + if (cw1200_powerup) { + gpiod_set_value(cw1200_powerup, 1); msleep(250); /* or more..? */ } - /* Enable RSTn signal */ - if (pdata->reset) { - gpio_set_value(pdata->reset, 1); + /* Deassert RSTn signal, note active low */ + if (cw1200_reset) { + gpiod_set_value(cw1200_reset, 0); msleep(50); /* Or more..? */ } return 0; diff --git a/drivers/net/wireless/st/cw1200/cw1200_spi.c b/drivers/net/wireless/st/cw1200/cw1200_spi.c index c82c0688b549..9df7f46588b4 100644 --- a/drivers/net/wireless/st/cw1200/cw1200_spi.c +++ b/drivers/net/wireless/st/cw1200/cw1200_spi.c @@ -11,7 +11,7 @@ */ #include -#include +#include #include #include #include @@ -38,6 +38,8 @@ struct hwbus_priv { const struct cw1200_platform_data_spi *pdata; spinlock_t lock; /* Serialize all bus operations */ wait_queue_head_t wq; + struct gpio_desc *reset; + struct gpio_desc *powerup; int claimed; }; @@ -275,12 +277,12 @@ static void cw1200_spi_irq_unsubscribe(struct hwbus_priv *self) free_irq(self->func->irq, self); } -static int cw1200_spi_off(const struct cw1200_platform_data_spi *pdata) +static int cw1200_spi_off(struct hwbus_priv *self, const struct cw1200_platform_data_spi *pdata) { - if (pdata->reset) { - gpio_set_value(pdata->reset, 0); + if (self->reset) { + /* Assert RESET, note active low */ + gpiod_set_value(self->reset, 1); msleep(30); /* Min is 2 * CLK32K cycles */ - gpio_free(pdata->reset); } if (pdata->power_ctrl) @@ -291,18 +293,12 @@ static int cw1200_spi_off(const struct cw1200_platform_data_spi *pdata) return 0; } -static int cw1200_spi_on(const struct cw1200_platform_data_spi *pdata) +static int cw1200_spi_on(struct hwbus_priv *self, const struct cw1200_platform_data_spi *pdata) { /* Ensure I/Os are pulled low */ - if (pdata->reset) { - gpio_request(pdata->reset, "cw1200_wlan_reset"); - gpio_direction_output(pdata->reset, 0); - } - if (pdata->powerup) { - gpio_request(pdata->powerup, "cw1200_wlan_powerup"); - gpio_direction_output(pdata->powerup, 0); - } - if (pdata->reset || pdata->powerup) + gpiod_direction_output(self->reset, 1); /* Active low */ + gpiod_direction_output(self->powerup, 0); + if (self->reset || self->powerup) msleep(10); /* Settle time? */ /* Enable 3v3 and 1v8 to hardware */ @@ -323,13 +319,13 @@ static int cw1200_spi_on(const struct cw1200_platform_data_spi *pdata) } /* Enable POWERUP signal */ - if (pdata->powerup) { - gpio_set_value(pdata->powerup, 1); + if (self->powerup) { + gpiod_set_value(self->powerup, 1); msleep(250); /* or more..? */ } - /* Enable RSTn signal */ - if (pdata->reset) { - gpio_set_value(pdata->reset, 1); + /* Assert RSTn signal, note active low */ + if (self->reset) { + gpiod_set_value(self->reset, 0); msleep(50); /* Or more..? */ } return 0; @@ -381,20 +377,33 @@ static int cw1200_spi_probe(struct spi_device *func) spi_get_chipselect(func, 0), func->mode, func->bits_per_word, func->max_speed_hz); - if (cw1200_spi_on(plat_data)) { + self = devm_kzalloc(&func->dev, sizeof(*self), GFP_KERNEL); + if (!self) { + pr_err("Can't allocate SPI hwbus_priv."); + return -ENOMEM; + } + + /* Request reset asserted */ + self->reset = devm_gpiod_get_optional(&func->dev, "reset", GPIOD_OUT_HIGH); + if (IS_ERR(self->reset)) + return dev_err_probe(&func->dev, PTR_ERR(self->reset), + "could not get reset GPIO\n"); + gpiod_set_consumer_name(self->reset, "cw1200_wlan_reset"); + + self->powerup = devm_gpiod_get_optional(&func->dev, "powerup", GPIOD_OUT_LOW); + if (IS_ERR(self->powerup)) + return dev_err_probe(&func->dev, PTR_ERR(self->powerup), + "could not get powerup GPIO\n"); + gpiod_set_consumer_name(self->reset, "cw1200_wlan_powerup"); + + if (cw1200_spi_on(self, plat_data)) { pr_err("spi_on() failed!\n"); - return -1; + return -ENODEV; } if (spi_setup(func)) { pr_err("spi_setup() failed!\n"); - return -1; - } - - self = devm_kzalloc(&func->dev, sizeof(*self), GFP_KERNEL); - if (!self) { - pr_err("Can't allocate SPI hwbus_priv."); - return -ENOMEM; + return -ENODEV; } self->pdata = plat_data; @@ -416,7 +425,7 @@ static int cw1200_spi_probe(struct spi_device *func) if (status) { cw1200_spi_irq_unsubscribe(self); - cw1200_spi_off(plat_data); + cw1200_spi_off(self, plat_data); } return status; @@ -434,7 +443,7 @@ static void cw1200_spi_disconnect(struct spi_device *func) self->core = NULL; } } - cw1200_spi_off(dev_get_platdata(&func->dev)); + cw1200_spi_off(self, dev_get_platdata(&func->dev)); } static int __maybe_unused cw1200_spi_suspend(struct device *dev) diff --git a/include/linux/platform_data/net-cw1200.h b/include/linux/platform_data/net-cw1200.h index c510734405bb..89d0ec6f7d46 100644 --- a/include/linux/platform_data/net-cw1200.h +++ b/include/linux/platform_data/net-cw1200.h @@ -14,8 +14,6 @@ struct cw1200_platform_data_spi { /* All others are optional */ bool have_5ghz; - int reset; /* GPIO to RSTn signal (0 disables) */ - int powerup; /* GPIO to POWERUP signal (0 disables) */ int (*power_ctrl)(const struct cw1200_platform_data_spi *pdata, bool enable); /* Control 3v3 / 1v8 supply */ int (*clk_ctrl)(const struct cw1200_platform_data_spi *pdata, @@ -30,8 +28,6 @@ struct cw1200_platform_data_sdio { /* All others are optional */ bool have_5ghz; bool no_nptb; /* SDIO hardware does not support non-power-of-2-blocksizes */ - int reset; /* GPIO to RSTn signal (0 disables) */ - int powerup; /* GPIO to POWERUP signal (0 disables) */ int irq; /* IRQ line or 0 to use SDIO IRQ */ int (*power_ctrl)(const struct cw1200_platform_data_sdio *pdata, bool enable); /* Control 3v3 / 1v8 supply */