From nobody Mon Dec 15 21:27:08 2025 Received: from mx.treblig.org (mx.treblig.org [46.235.229.95]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 55A522512D1; Wed, 25 Jun 2025 13:33:40 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=46.235.229.95 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750858424; cv=none; b=k5Xlz3VLYVMr9n+TGyyl3fJUVSP9Mn2PqGqwDzqSBMlDlJRwZyIpU7gLRZGpPUb+fMilFVRWOW8DiCmAN+zpMFd3iS8unlhQkJjQ/UvUhmGGvT4mxUTqhyhWBhwQDdQx+W82p2dq84Hw6AJRbCnbETLFNew3xDnBQIYTDN25alU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750858424; c=relaxed/simple; bh=5NwzVdzM+RuogmvoF5tFxiCn/H3HMrezURKUsH0SQhA=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=b8S01llkWLbCR5D75tLhiQZOEg60bwPYhuymhJZVkKvSv/1I8OTSOImtCMXlyEpFz8S+rwPZM26jGajWj1lIA1z2+32xy6+67BBogdHaKUMvfqbZamrgt0+PCP1vOH+jW+gTslo5xT8I3Yo1CN7BnIonfMUKOIQ0YzFZRCt6IzM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=treblig.org; spf=pass smtp.mailfrom=treblig.org; dkim=pass (2048-bit key) header.d=treblig.org header.i=@treblig.org header.b=MsSgeEcm; arc=none smtp.client-ip=46.235.229.95 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=treblig.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=treblig.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=treblig.org header.i=@treblig.org header.b="MsSgeEcm" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=treblig.org ; s=bytemarkmx; h=MIME-Version:Message-ID:Date:Subject:From:Content-Type:From :Subject; bh=b/7833Uc75z1SXx1xufwgNOVFatyQPtE9AhFGcbjLGQ=; b=MsSgeEcmXg5evKHw 4MYGQbRMN+dIxLIC0BqbWyYId1u/aokc0YhDsWvpaGfRRcf0kCRdmdX3WbHJc+En7l2pglpC0X2K/ JGRSy/Jf2eGV9yCDQtcmh7ROrXmkOxGDbsqfbVIJnEZX9yULznql+kclnJdovP7iek42FJLvjvkrH sdKbKn18JWwx6JuWIW+Et3yXNsxHg0gdlA21R+Rf4XkI8uUUzwRur+WmXk/wF4ESU9xYOhL0TnLjM 3k6NA1wElfAakDMaw5a2Nb+2k7c2nerefFAX562ahAM33o6ZDTS7CbrXLahhTL91Zm4igo2bWyuPU Vi8GkILK/+kMf5dMkA==; Received: from localhost ([127.0.0.1] helo=dalek.home.treblig.org) by mx.treblig.org with esmtp (Exim 4.96) (envelope-from ) id 1uUQFm-00Bvly-1D; Wed, 25 Jun 2025 13:33:30 +0000 From: linux@treblig.org To: arnd@arndb.de, lee@kernel.org, mchehab@kernel.org, lgirdwood@gmail.com, broonie@kernel.org, perex@perex.cz, tiwai@suse.com Cc: linux-media@vger.kernel.org, linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org, "Dr. David Alan Gilbert" Subject: [PATCH 1/4] media: radio-wl1273: Remove Date: Wed, 25 Jun 2025 14:32:55 +0100 Message-ID: <20250625133258.78133-2-linux@treblig.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250625133258.78133-1-linux@treblig.org> References: <20250625133258.78133-1-linux@treblig.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: "Dr. David Alan Gilbert" The wl1273 FM radio is on Arnd's unused driver list: https://lore.kernel.org/lkml/a15bb180-401d-49ad-a212-0c81d613fbc8@app.fas= tmail.com/ remove the radio component itself. Signed-off-by: Dr. David Alan Gilbert Acked-by: Arnd Bergmann Reviewed-by: Laurent Pinchart --- drivers/media/radio/Kconfig | 17 - drivers/media/radio/Makefile | 1 - drivers/media/radio/radio-wl1273.c | 2159 ---------------------------- 3 files changed, 2177 deletions(-) delete mode 100644 drivers/media/radio/radio-wl1273.c diff --git a/drivers/media/radio/Kconfig b/drivers/media/radio/Kconfig index 72776d08046a..bbbdd054ba64 100644 --- a/drivers/media/radio/Kconfig +++ b/drivers/media/radio/Kconfig @@ -141,23 +141,6 @@ config RADIO_TIMBERDALE found behind the Timberdale FPGA on the Russellville board. Enabling this driver will automatically select the DSP and tuner. =20 -config RADIO_WL1273 - tristate "Texas Instruments WL1273 I2C FM Radio" - depends on I2C - select MFD_CORE - select MFD_WL1273_CORE - select FW_LOADER - help - Choose Y here if you have this FM radio chip. - - In order to control your radio card, you will need to use programs - that are compatible with the Video For Linux 2 API. Information on - this API and pointers to "v4l2" programs may be found at - . - - To compile this driver as a module, choose M here: the - module will be called radio-wl1273. - config USB_DSBR tristate "D-Link/GemTek USB FM radio support" depends on USB diff --git a/drivers/media/radio/Makefile b/drivers/media/radio/Makefile index 1ff46f3a6ed3..f54693ebdb30 100644 --- a/drivers/media/radio/Makefile +++ b/drivers/media/radio/Makefile @@ -30,7 +30,6 @@ obj-$(CONFIG_RADIO_TERRATEC) +=3D radio-terratec.o obj-$(CONFIG_RADIO_TIMBERDALE) +=3D radio-timb.o obj-$(CONFIG_RADIO_TRUST) +=3D radio-trust.o obj-$(CONFIG_RADIO_TYPHOON) +=3D radio-typhoon.o -obj-$(CONFIG_RADIO_WL1273) +=3D radio-wl1273.o obj-$(CONFIG_RADIO_ZOLTRIX) +=3D radio-zoltrix.o =20 obj-$(CONFIG_USB_DSBR) +=3D dsbr100.o diff --git a/drivers/media/radio/radio-wl1273.c b/drivers/media/radio/radio= -wl1273.c deleted file mode 100644 index f55217ccf2b8..000000000000 --- a/drivers/media/radio/radio-wl1273.c +++ /dev/null @@ -1,2159 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * Driver for the Texas Instruments WL1273 FM radio. - * - * Copyright (C) 2011 Nokia Corporation - * Author: Matti J. Aaltonen - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#define DRIVER_DESC "Wl1273 FM Radio" - -#define WL1273_POWER_SET_OFF 0 -#define WL1273_POWER_SET_FM BIT(0) -#define WL1273_POWER_SET_RDS BIT(1) -#define WL1273_POWER_SET_RETENTION BIT(4) - -#define WL1273_PUPD_SET_OFF 0x00 -#define WL1273_PUPD_SET_ON 0x01 -#define WL1273_PUPD_SET_RETENTION 0x10 - -#define WL1273_FREQ(x) (x * 10000 / 625) -#define WL1273_INV_FREQ(x) (x * 625 / 10000) - -/* - * static int radio_nr - The number of the radio device - * - * The default is 0. - */ -static int radio_nr; -module_param(radio_nr, int, 0); -MODULE_PARM_DESC(radio_nr, "The number of the radio device. Default =3D 0"= ); - -struct wl1273_device { - char *bus_type; - - u8 forbidden; - unsigned int preemphasis; - unsigned int spacing; - unsigned int tx_power; - unsigned int rx_frequency; - unsigned int tx_frequency; - unsigned int rangelow; - unsigned int rangehigh; - unsigned int band; - bool stereo; - - /* RDS */ - unsigned int rds_on; - - wait_queue_head_t read_queue; - struct mutex lock; /* for serializing fm radio operations */ - struct completion busy; - - unsigned char *buffer; - unsigned int buf_size; - unsigned int rd_index; - unsigned int wr_index; - - /* Selected interrupts */ - u16 irq_flags; - u16 irq_received; - - struct v4l2_ctrl_handler ctrl_handler; - struct v4l2_device v4l2dev; - struct video_device videodev; - struct device *dev; - struct wl1273_core *core; - struct file *owner; - char *write_buf; - unsigned int rds_users; -}; - -#define WL1273_IRQ_MASK (WL1273_FR_EVENT | \ - WL1273_POW_ENB_EVENT) - -/* - * static unsigned int rds_buf - the number of RDS buffer blocks used. - * - * The default number is 100. - */ -static unsigned int rds_buf =3D 100; -module_param(rds_buf, uint, 0); -MODULE_PARM_DESC(rds_buf, "Number of RDS buffer entries. Default =3D 100"); - -static int wl1273_fm_write_fw(struct wl1273_core *core, - __u8 *fw, int len) -{ - struct i2c_client *client =3D core->client; - struct i2c_msg msg; - int i, r =3D 0; - - msg.addr =3D client->addr; - msg.flags =3D 0; - - for (i =3D 0; i <=3D len; i++) { - msg.len =3D fw[0]; - msg.buf =3D fw + 1; - - fw +=3D msg.len + 1; - dev_dbg(&client->dev, "%s:len[%d]: %d\n", __func__, i, msg.len); - - r =3D i2c_transfer(client->adapter, &msg, 1); - if (r < 0 && i < len + 1) - break; - } - - dev_dbg(&client->dev, "%s: i: %d\n", __func__, i); - dev_dbg(&client->dev, "%s: len + 1: %d\n", __func__, len + 1); - - /* Last transfer always fails. */ - if (i =3D=3D len || r =3D=3D 1) - r =3D 0; - - return r; -} - -#define WL1273_FIFO_HAS_DATA(status) (1 << 5 & status) -#define WL1273_RDS_CORRECTABLE_ERROR (1 << 3) -#define WL1273_RDS_UNCORRECTABLE_ERROR (1 << 4) - -static int wl1273_fm_rds(struct wl1273_device *radio) -{ - struct wl1273_core *core =3D radio->core; - struct i2c_client *client =3D core->client; - u16 val; - u8 b0 =3D WL1273_RDS_DATA_GET, status; - struct v4l2_rds_data rds =3D { 0, 0, 0 }; - struct i2c_msg msg[] =3D { - { - .addr =3D client->addr, - .flags =3D 0, - .buf =3D &b0, - .len =3D 1, - }, - { - .addr =3D client->addr, - .flags =3D I2C_M_RD, - .buf =3D (u8 *) &rds, - .len =3D sizeof(rds), - } - }; - int r; - - if (core->mode !=3D WL1273_MODE_RX) - return 0; - - r =3D core->read(core, WL1273_RDS_SYNC_GET, &val); - if (r) - return r; - - if ((val & 0x01) =3D=3D 0) { - /* RDS decoder not synchronized */ - return -EAGAIN; - } - - /* copy all four RDS blocks to internal buffer */ - do { - r =3D i2c_transfer(client->adapter, msg, ARRAY_SIZE(msg)); - if (r !=3D ARRAY_SIZE(msg)) { - dev_err(radio->dev, WL1273_FM_DRIVER_NAME - ": %s: read_rds error r =3D=3D %i)\n", - __func__, r); - } - - status =3D rds.block; - - if (!WL1273_FIFO_HAS_DATA(status)) - break; - - /* copy bits 0-2 (the block ID) to bits 3-5 */ - rds.block =3D V4L2_RDS_BLOCK_MSK & status; - rds.block |=3D rds.block << 3; - - /* copy the error bits to standard positions */ - if (WL1273_RDS_UNCORRECTABLE_ERROR & status) { - rds.block |=3D V4L2_RDS_BLOCK_ERROR; - rds.block &=3D ~V4L2_RDS_BLOCK_CORRECTED; - } else if (WL1273_RDS_CORRECTABLE_ERROR & status) { - rds.block &=3D ~V4L2_RDS_BLOCK_ERROR; - rds.block |=3D V4L2_RDS_BLOCK_CORRECTED; - } - - /* copy RDS block to internal buffer */ - memcpy(&radio->buffer[radio->wr_index], &rds, RDS_BLOCK_SIZE); - radio->wr_index +=3D 3; - - /* wrap write pointer */ - if (radio->wr_index >=3D radio->buf_size) - radio->wr_index =3D 0; - - /* check for overflow & start over */ - if (radio->wr_index =3D=3D radio->rd_index) { - dev_dbg(radio->dev, "RDS OVERFLOW"); - - radio->rd_index =3D 0; - radio->wr_index =3D 0; - break; - } - } while (WL1273_FIFO_HAS_DATA(status)); - - /* wake up read queue */ - if (radio->wr_index !=3D radio->rd_index) - wake_up_interruptible(&radio->read_queue); - - return 0; -} - -static irqreturn_t wl1273_fm_irq_thread_handler(int irq, void *dev_id) -{ - struct wl1273_device *radio =3D dev_id; - struct wl1273_core *core =3D radio->core; - u16 flags; - int r; - - r =3D core->read(core, WL1273_FLAG_GET, &flags); - if (r) - goto out; - - if (flags & WL1273_BL_EVENT) { - radio->irq_received =3D flags; - dev_dbg(radio->dev, "IRQ: BL\n"); - } - - if (flags & WL1273_RDS_EVENT) { - msleep(200); - - wl1273_fm_rds(radio); - } - - if (flags & WL1273_BBLK_EVENT) - dev_dbg(radio->dev, "IRQ: BBLK\n"); - - if (flags & WL1273_LSYNC_EVENT) - dev_dbg(radio->dev, "IRQ: LSYNC\n"); - - if (flags & WL1273_LEV_EVENT) { - u16 level; - - r =3D core->read(core, WL1273_RSSI_LVL_GET, &level); - if (r) - goto out; - - if (level > 14) - dev_dbg(radio->dev, "IRQ: LEV: 0x%x04\n", level); - } - - if (flags & WL1273_IFFR_EVENT) - dev_dbg(radio->dev, "IRQ: IFFR\n"); - - if (flags & WL1273_PI_EVENT) - dev_dbg(radio->dev, "IRQ: PI\n"); - - if (flags & WL1273_PD_EVENT) - dev_dbg(radio->dev, "IRQ: PD\n"); - - if (flags & WL1273_STIC_EVENT) - dev_dbg(radio->dev, "IRQ: STIC\n"); - - if (flags & WL1273_MAL_EVENT) - dev_dbg(radio->dev, "IRQ: MAL\n"); - - if (flags & WL1273_POW_ENB_EVENT) { - complete(&radio->busy); - dev_dbg(radio->dev, "NOT BUSY\n"); - dev_dbg(radio->dev, "IRQ: POW_ENB\n"); - } - - if (flags & WL1273_SCAN_OVER_EVENT) - dev_dbg(radio->dev, "IRQ: SCAN_OVER\n"); - - if (flags & WL1273_ERROR_EVENT) - dev_dbg(radio->dev, "IRQ: ERROR\n"); - - if (flags & WL1273_FR_EVENT) { - u16 freq; - - dev_dbg(radio->dev, "IRQ: FR:\n"); - - if (core->mode =3D=3D WL1273_MODE_RX) { - r =3D core->write(core, WL1273_TUNER_MODE_SET, - TUNER_MODE_STOP_SEARCH); - if (r) { - dev_err(radio->dev, - "%s: TUNER_MODE_SET fails: %d\n", - __func__, r); - goto out; - } - - r =3D core->read(core, WL1273_FREQ_SET, &freq); - if (r) - goto out; - - if (radio->band =3D=3D WL1273_BAND_JAPAN) - radio->rx_frequency =3D WL1273_BAND_JAPAN_LOW + - freq * 50; - else - radio->rx_frequency =3D WL1273_BAND_OTHER_LOW + - freq * 50; - /* - * The driver works better with this msleep, - * the documentation doesn't mention it. - */ - usleep_range(10000, 15000); - - dev_dbg(radio->dev, "%dkHz\n", radio->rx_frequency); - - } else { - r =3D core->read(core, WL1273_CHANL_SET, &freq); - if (r) - goto out; - - dev_dbg(radio->dev, "%dkHz\n", freq); - } - dev_dbg(radio->dev, "%s: NOT BUSY\n", __func__); - } - -out: - core->write(core, WL1273_INT_MASK_SET, radio->irq_flags); - complete(&radio->busy); - - return IRQ_HANDLED; -} - -static int wl1273_fm_set_tx_freq(struct wl1273_device *radio, unsigned int= freq) -{ - struct wl1273_core *core =3D radio->core; - int r =3D 0; - unsigned long t; - - if (freq < WL1273_BAND_TX_LOW) { - dev_err(radio->dev, - "Frequency out of range: %d < %d\n", freq, - WL1273_BAND_TX_LOW); - return -ERANGE; - } - - if (freq > WL1273_BAND_TX_HIGH) { - dev_err(radio->dev, - "Frequency out of range: %d > %d\n", freq, - WL1273_BAND_TX_HIGH); - return -ERANGE; - } - - /* - * The driver works better with this sleep, - * the documentation doesn't mention it. - */ - usleep_range(5000, 10000); - - dev_dbg(radio->dev, "%s: freq: %d kHz\n", __func__, freq); - - /* Set the current tx channel */ - r =3D core->write(core, WL1273_CHANL_SET, freq / 10); - if (r) - return r; - - reinit_completion(&radio->busy); - - /* wait for the FR IRQ */ - t =3D wait_for_completion_timeout(&radio->busy, msecs_to_jiffies(2000)); - if (!t) - return -ETIMEDOUT; - - dev_dbg(radio->dev, "WL1273_CHANL_SET: %lu\n", t); - - /* Enable the output power */ - r =3D core->write(core, WL1273_POWER_ENB_SET, 1); - if (r) - return r; - - reinit_completion(&radio->busy); - - /* wait for the POWER_ENB IRQ */ - t =3D wait_for_completion_timeout(&radio->busy, msecs_to_jiffies(1000)); - if (!t) - return -ETIMEDOUT; - - radio->tx_frequency =3D freq; - dev_dbg(radio->dev, "WL1273_POWER_ENB_SET: %lu\n", t); - - return 0; -} - -static int wl1273_fm_set_rx_freq(struct wl1273_device *radio, unsigned int= freq) -{ - struct wl1273_core *core =3D radio->core; - int r, f; - unsigned long t; - - if (freq < radio->rangelow) { - dev_err(radio->dev, - "Frequency out of range: %d < %d\n", freq, - radio->rangelow); - r =3D -ERANGE; - goto err; - } - - if (freq > radio->rangehigh) { - dev_err(radio->dev, - "Frequency out of range: %d > %d\n", freq, - radio->rangehigh); - r =3D -ERANGE; - goto err; - } - - dev_dbg(radio->dev, "%s: %dkHz\n", __func__, freq); - - core->write(core, WL1273_INT_MASK_SET, radio->irq_flags); - - if (radio->band =3D=3D WL1273_BAND_JAPAN) - f =3D (freq - WL1273_BAND_JAPAN_LOW) / 50; - else - f =3D (freq - WL1273_BAND_OTHER_LOW) / 50; - - r =3D core->write(core, WL1273_FREQ_SET, f); - if (r) { - dev_err(radio->dev, "FREQ_SET fails\n"); - goto err; - } - - r =3D core->write(core, WL1273_TUNER_MODE_SET, TUNER_MODE_PRESET); - if (r) { - dev_err(radio->dev, "TUNER_MODE_SET fails\n"); - goto err; - } - - reinit_completion(&radio->busy); - - t =3D wait_for_completion_timeout(&radio->busy, msecs_to_jiffies(2000)); - if (!t) { - dev_err(radio->dev, "%s: TIMEOUT\n", __func__); - return -ETIMEDOUT; - } - - radio->rd_index =3D 0; - radio->wr_index =3D 0; - radio->rx_frequency =3D freq; - return 0; -err: - return r; -} - -static int wl1273_fm_get_freq(struct wl1273_device *radio) -{ - struct wl1273_core *core =3D radio->core; - unsigned int freq; - u16 f; - int r; - - if (core->mode =3D=3D WL1273_MODE_RX) { - r =3D core->read(core, WL1273_FREQ_SET, &f); - if (r) - return r; - - dev_dbg(radio->dev, "Freq get: 0x%04x\n", f); - if (radio->band =3D=3D WL1273_BAND_JAPAN) - freq =3D WL1273_BAND_JAPAN_LOW + 50 * f; - else - freq =3D WL1273_BAND_OTHER_LOW + 50 * f; - } else { - r =3D core->read(core, WL1273_CHANL_SET, &f); - if (r) - return r; - - freq =3D f * 10; - } - - return freq; -} - -/** - * wl1273_fm_upload_firmware_patch() - Upload the firmware. - * @radio: A pointer to the device struct. - * - * The firmware file consists of arrays of bytes where the first byte - * gives the array length. The first byte in the file gives the - * number of these arrays. - */ -static int wl1273_fm_upload_firmware_patch(struct wl1273_device *radio) -{ - struct wl1273_core *core =3D radio->core; - unsigned int packet_num; - const struct firmware *fw_p; - const char *fw_name =3D "radio-wl1273-fw.bin"; - struct device *dev =3D radio->dev; - __u8 *ptr; - int r; - - dev_dbg(dev, "%s:\n", __func__); - - /* - * Uploading the firmware patch is not always necessary, - * so we only print an info message. - */ - if (request_firmware(&fw_p, fw_name, dev)) { - dev_info(dev, "%s - %s not found\n", __func__, fw_name); - - return 0; - } - - ptr =3D (__u8 *) fw_p->data; - packet_num =3D ptr[0]; - dev_dbg(dev, "%s: packets: %d\n", __func__, packet_num); - - r =3D wl1273_fm_write_fw(core, ptr + 1, packet_num); - if (r) { - dev_err(dev, "FW upload error: %d\n", r); - goto out; - } - - /* ignore possible error here */ - core->write(core, WL1273_RESET, 0); - - dev_dbg(dev, "%s - download OK, r: %d\n", __func__, r); -out: - release_firmware(fw_p); - return r; -} - -static int wl1273_fm_stop(struct wl1273_device *radio) -{ - struct wl1273_core *core =3D radio->core; - - if (core->mode =3D=3D WL1273_MODE_RX) { - int r =3D core->write(core, WL1273_POWER_SET, - WL1273_POWER_SET_OFF); - if (r) - dev_err(radio->dev, "%s: POWER_SET fails: %d\n", - __func__, r); - } else if (core->mode =3D=3D WL1273_MODE_TX) { - int r =3D core->write(core, WL1273_PUPD_SET, - WL1273_PUPD_SET_OFF); - if (r) - dev_err(radio->dev, - "%s: PUPD_SET fails: %d\n", __func__, r); - } - - if (core->pdata->disable) { - core->pdata->disable(); - dev_dbg(radio->dev, "Back to reset\n"); - } - - return 0; -} - -static int wl1273_fm_start(struct wl1273_device *radio, int new_mode) -{ - struct wl1273_core *core =3D radio->core; - struct wl1273_fm_platform_data *pdata =3D core->pdata; - struct device *dev =3D radio->dev; - int r =3D -EINVAL; - - if (pdata->enable && core->mode =3D=3D WL1273_MODE_OFF) { - dev_dbg(radio->dev, "Out of reset\n"); - - pdata->enable(); - msleep(250); - } - - if (new_mode =3D=3D WL1273_MODE_RX) { - u16 val =3D WL1273_POWER_SET_FM; - - if (radio->rds_on) - val |=3D WL1273_POWER_SET_RDS; - - /* If this fails try again */ - r =3D core->write(core, WL1273_POWER_SET, val); - if (r) { - msleep(100); - - r =3D core->write(core, WL1273_POWER_SET, val); - if (r) { - dev_err(dev, "%s: POWER_SET fails\n", __func__); - goto fail; - } - } - - /* rds buffer configuration */ - radio->wr_index =3D 0; - radio->rd_index =3D 0; - - } else if (new_mode =3D=3D WL1273_MODE_TX) { - /* If this fails try again once */ - r =3D core->write(core, WL1273_PUPD_SET, WL1273_PUPD_SET_ON); - if (r) { - msleep(100); - r =3D core->write(core, WL1273_PUPD_SET, - WL1273_PUPD_SET_ON); - if (r) { - dev_err(dev, "%s: PUPD_SET fails\n", __func__); - goto fail; - } - } - - if (radio->rds_on) { - r =3D core->write(core, WL1273_RDS_DATA_ENB, 1); - if (r) { - dev_err(dev, "%s: RDS_DATA_ENB ON fails\n", - __func__); - goto fail; - } - } else { - r =3D core->write(core, WL1273_RDS_DATA_ENB, 0); - if (r) { - dev_err(dev, "%s: RDS_DATA_ENB OFF fails\n", - __func__); - goto fail; - } - } - } else { - dev_warn(dev, "%s: Illegal mode.\n", __func__); - } - - if (core->mode =3D=3D WL1273_MODE_OFF) { - r =3D wl1273_fm_upload_firmware_patch(radio); - if (r) - dev_warn(dev, "Firmware upload failed.\n"); - - /* - * Sometimes the chip is in a wrong power state at this point. - * So we set the power once again. - */ - if (new_mode =3D=3D WL1273_MODE_RX) { - u16 val =3D WL1273_POWER_SET_FM; - - if (radio->rds_on) - val |=3D WL1273_POWER_SET_RDS; - - r =3D core->write(core, WL1273_POWER_SET, val); - if (r) { - dev_err(dev, "%s: POWER_SET fails\n", __func__); - goto fail; - } - } else if (new_mode =3D=3D WL1273_MODE_TX) { - r =3D core->write(core, WL1273_PUPD_SET, - WL1273_PUPD_SET_ON); - if (r) { - dev_err(dev, "%s: PUPD_SET fails\n", __func__); - goto fail; - } - } - } - - return 0; -fail: - if (pdata->disable) - pdata->disable(); - - dev_dbg(dev, "%s: return: %d\n", __func__, r); - return r; -} - -static int wl1273_fm_suspend(struct wl1273_device *radio) -{ - struct wl1273_core *core =3D radio->core; - int r; - - /* Cannot go from OFF to SUSPENDED */ - if (core->mode =3D=3D WL1273_MODE_RX) - r =3D core->write(core, WL1273_POWER_SET, - WL1273_POWER_SET_RETENTION); - else if (core->mode =3D=3D WL1273_MODE_TX) - r =3D core->write(core, WL1273_PUPD_SET, - WL1273_PUPD_SET_RETENTION); - else - r =3D -EINVAL; - - if (r) { - dev_err(radio->dev, "%s: POWER_SET fails: %d\n", __func__, r); - goto out; - } - -out: - return r; -} - -static int wl1273_fm_set_mode(struct wl1273_device *radio, int mode) -{ - struct wl1273_core *core =3D radio->core; - struct device *dev =3D radio->dev; - int old_mode; - int r; - - dev_dbg(dev, "%s\n", __func__); - dev_dbg(dev, "Forbidden modes: 0x%02x\n", radio->forbidden); - - old_mode =3D core->mode; - if (mode & radio->forbidden) { - r =3D -EPERM; - goto out; - } - - switch (mode) { - case WL1273_MODE_RX: - case WL1273_MODE_TX: - r =3D wl1273_fm_start(radio, mode); - if (r) { - dev_err(dev, "%s: Cannot start.\n", __func__); - wl1273_fm_stop(radio); - goto out; - } - - core->mode =3D mode; - r =3D core->write(core, WL1273_INT_MASK_SET, radio->irq_flags); - if (r) { - dev_err(dev, "INT_MASK_SET fails.\n"); - goto out; - } - - /* remember previous settings */ - if (mode =3D=3D WL1273_MODE_RX) { - r =3D wl1273_fm_set_rx_freq(radio, radio->rx_frequency); - if (r) { - dev_err(dev, "set freq fails: %d.\n", r); - goto out; - } - - r =3D core->set_volume(core, core->volume); - if (r) { - dev_err(dev, "set volume fails: %d.\n", r); - goto out; - } - - dev_dbg(dev, "%s: Set vol: %d.\n", __func__, - core->volume); - } else { - r =3D wl1273_fm_set_tx_freq(radio, radio->tx_frequency); - if (r) { - dev_err(dev, "set freq fails: %d.\n", r); - goto out; - } - } - - dev_dbg(radio->dev, "%s: Set audio mode.\n", __func__); - - r =3D core->set_audio(core, core->audio_mode); - if (r) - dev_err(dev, "Cannot set audio mode.\n"); - break; - - case WL1273_MODE_OFF: - r =3D wl1273_fm_stop(radio); - if (r) - dev_err(dev, "%s: Off fails: %d\n", __func__, r); - else - core->mode =3D WL1273_MODE_OFF; - - break; - - case WL1273_MODE_SUSPENDED: - r =3D wl1273_fm_suspend(radio); - if (r) - dev_err(dev, "%s: Suspend fails: %d\n", __func__, r); - else - core->mode =3D WL1273_MODE_SUSPENDED; - - break; - - default: - dev_err(dev, "%s: Unknown mode: %d\n", __func__, mode); - r =3D -EINVAL; - break; - } -out: - if (r) - core->mode =3D old_mode; - - return r; -} - -static int wl1273_fm_set_seek(struct wl1273_device *radio, - unsigned int wrap_around, - unsigned int seek_upward, - int level) -{ - struct wl1273_core *core =3D radio->core; - int r =3D 0; - unsigned int dir =3D (seek_upward =3D=3D 0) ? 0 : 1; - unsigned int f; - - f =3D radio->rx_frequency; - dev_dbg(radio->dev, "rx_frequency: %d\n", f); - - if (dir && f + radio->spacing <=3D radio->rangehigh) - r =3D wl1273_fm_set_rx_freq(radio, f + radio->spacing); - else if (dir && wrap_around) - r =3D wl1273_fm_set_rx_freq(radio, radio->rangelow); - else if (f - radio->spacing >=3D radio->rangelow) - r =3D wl1273_fm_set_rx_freq(radio, f - radio->spacing); - else if (wrap_around) - r =3D wl1273_fm_set_rx_freq(radio, radio->rangehigh); - - if (r) - goto out; - - if (level < SCHAR_MIN || level > SCHAR_MAX) - return -EINVAL; - - reinit_completion(&radio->busy); - dev_dbg(radio->dev, "%s: BUSY\n", __func__); - - r =3D core->write(core, WL1273_INT_MASK_SET, radio->irq_flags); - if (r) - goto out; - - dev_dbg(radio->dev, "%s\n", __func__); - - r =3D core->write(core, WL1273_SEARCH_LVL_SET, level); - if (r) - goto out; - - r =3D core->write(core, WL1273_SEARCH_DIR_SET, dir); - if (r) - goto out; - - r =3D core->write(core, WL1273_TUNER_MODE_SET, TUNER_MODE_AUTO_SEEK); - if (r) - goto out; - - /* wait for the FR IRQ */ - wait_for_completion_timeout(&radio->busy, msecs_to_jiffies(1000)); - if (!(radio->irq_received & WL1273_BL_EVENT)) { - r =3D -ETIMEDOUT; - goto out; - } - - radio->irq_received &=3D ~WL1273_BL_EVENT; - - if (!wrap_around) - goto out; - - /* Wrap around */ - dev_dbg(radio->dev, "Wrap around in HW seek.\n"); - - if (seek_upward) - f =3D radio->rangelow; - else - f =3D radio->rangehigh; - - r =3D wl1273_fm_set_rx_freq(radio, f); - if (r) - goto out; - - reinit_completion(&radio->busy); - dev_dbg(radio->dev, "%s: BUSY\n", __func__); - - r =3D core->write(core, WL1273_TUNER_MODE_SET, TUNER_MODE_AUTO_SEEK); - if (r) - goto out; - - /* wait for the FR IRQ */ - if (!wait_for_completion_timeout(&radio->busy, msecs_to_jiffies(1000))) - r =3D -ETIMEDOUT; -out: - dev_dbg(radio->dev, "%s: Err: %d\n", __func__, r); - return r; -} - -/** - * wl1273_fm_get_tx_ctune() - Get the TX tuning capacitor value. - * @radio: A pointer to the device struct. - */ -static unsigned int wl1273_fm_get_tx_ctune(struct wl1273_device *radio) -{ - struct wl1273_core *core =3D radio->core; - struct device *dev =3D radio->dev; - u16 val; - int r; - - if (core->mode =3D=3D WL1273_MODE_OFF || - core->mode =3D=3D WL1273_MODE_SUSPENDED) - return -EPERM; - - r =3D core->read(core, WL1273_READ_FMANT_TUNE_VALUE, &val); - if (r) { - dev_err(dev, "%s: read error: %d\n", __func__, r); - goto out; - } - -out: - return val; -} - -/** - * wl1273_fm_set_preemphasis() - Set the TX pre-emphasis value. - * @radio: A pointer to the device struct. - * @preemphasis: The new pre-amphasis value. - * - * Possible pre-emphasis values are: V4L2_PREEMPHASIS_DISABLED, - * V4L2_PREEMPHASIS_50_uS and V4L2_PREEMPHASIS_75_uS. - */ -static int wl1273_fm_set_preemphasis(struct wl1273_device *radio, - unsigned int preemphasis) -{ - struct wl1273_core *core =3D radio->core; - int r; - u16 em; - - if (core->mode =3D=3D WL1273_MODE_OFF || - core->mode =3D=3D WL1273_MODE_SUSPENDED) - return -EPERM; - - mutex_lock(&core->lock); - - switch (preemphasis) { - case V4L2_PREEMPHASIS_DISABLED: - em =3D 1; - break; - case V4L2_PREEMPHASIS_50_uS: - em =3D 0; - break; - case V4L2_PREEMPHASIS_75_uS: - em =3D 2; - break; - default: - r =3D -EINVAL; - goto out; - } - - r =3D core->write(core, WL1273_PREMPH_SET, em); - if (r) - goto out; - - radio->preemphasis =3D preemphasis; - -out: - mutex_unlock(&core->lock); - return r; -} - -static int wl1273_fm_rds_on(struct wl1273_device *radio) -{ - struct wl1273_core *core =3D radio->core; - int r; - - dev_dbg(radio->dev, "%s\n", __func__); - if (radio->rds_on) - return 0; - - r =3D core->write(core, WL1273_POWER_SET, - WL1273_POWER_SET_FM | WL1273_POWER_SET_RDS); - if (r) - goto out; - - r =3D wl1273_fm_set_rx_freq(radio, radio->rx_frequency); - if (r) - dev_err(radio->dev, "set freq fails: %d.\n", r); -out: - return r; -} - -static int wl1273_fm_rds_off(struct wl1273_device *radio) -{ - struct wl1273_core *core =3D radio->core; - int r; - - if (!radio->rds_on) - return 0; - - radio->irq_flags &=3D ~WL1273_RDS_EVENT; - - r =3D core->write(core, WL1273_INT_MASK_SET, radio->irq_flags); - if (r) - goto out; - - /* Service pending read */ - wake_up_interruptible(&radio->read_queue); - - dev_dbg(radio->dev, "%s\n", __func__); - - r =3D core->write(core, WL1273_POWER_SET, WL1273_POWER_SET_FM); - if (r) - goto out; - - r =3D wl1273_fm_set_rx_freq(radio, radio->rx_frequency); - if (r) - dev_err(radio->dev, "set freq fails: %d.\n", r); -out: - dev_dbg(radio->dev, "%s: exiting...\n", __func__); - - return r; -} - -static int wl1273_fm_set_rds(struct wl1273_device *radio, unsigned int new= _mode) -{ - int r =3D 0; - struct wl1273_core *core =3D radio->core; - - if (core->mode =3D=3D WL1273_MODE_OFF || - core->mode =3D=3D WL1273_MODE_SUSPENDED) - return -EPERM; - - if (new_mode =3D=3D WL1273_RDS_RESET) { - r =3D core->write(core, WL1273_RDS_CNTRL_SET, 1); - return r; - } - - if (core->mode =3D=3D WL1273_MODE_TX && new_mode =3D=3D WL1273_RDS_OFF) { - r =3D core->write(core, WL1273_RDS_DATA_ENB, 0); - } else if (core->mode =3D=3D WL1273_MODE_TX && new_mode =3D=3D WL1273_RDS= _ON) { - r =3D core->write(core, WL1273_RDS_DATA_ENB, 1); - } else if (core->mode =3D=3D WL1273_MODE_RX && new_mode =3D=3D WL1273_RDS= _OFF) { - r =3D wl1273_fm_rds_off(radio); - } else if (core->mode =3D=3D WL1273_MODE_RX && new_mode =3D=3D WL1273_RDS= _ON) { - r =3D wl1273_fm_rds_on(radio); - } else { - dev_err(radio->dev, "%s: Unknown mode: %d\n", - __func__, new_mode); - r =3D -EINVAL; - } - - if (!r) - radio->rds_on =3D new_mode =3D=3D WL1273_RDS_ON; - - return r; -} - -static ssize_t wl1273_fm_fops_write(struct file *file, const char __user *= buf, - size_t count, loff_t *ppos) -{ - struct wl1273_device *radio =3D video_get_drvdata(video_devdata(file)); - struct wl1273_core *core =3D radio->core; - u16 val; - int r; - - dev_dbg(radio->dev, "%s\n", __func__); - - if (core->mode !=3D WL1273_MODE_TX) - return count; - - if (radio->rds_users =3D=3D 0) { - dev_warn(radio->dev, "%s: RDS not on.\n", __func__); - return 0; - } - - if (mutex_lock_interruptible(&core->lock)) - return -EINTR; - /* - * Multiple processes can open the device, but only - * one gets to write to it. - */ - if (radio->owner && radio->owner !=3D file) { - r =3D -EBUSY; - goto out; - } - radio->owner =3D file; - - /* Manual Mode */ - if (count > 255) - val =3D 255; - else - val =3D count; - - core->write(core, WL1273_RDS_CONFIG_DATA_SET, val); - - if (copy_from_user(radio->write_buf + 1, buf, val)) { - r =3D -EFAULT; - goto out; - } - - dev_dbg(radio->dev, "Count: %d\n", val); - dev_dbg(radio->dev, "From user: \"%s\"\n", radio->write_buf); - - radio->write_buf[0] =3D WL1273_RDS_DATA_SET; - core->write_data(core, radio->write_buf, val + 1); - - r =3D val; -out: - mutex_unlock(&core->lock); - - return r; -} - -static __poll_t wl1273_fm_fops_poll(struct file *file, - struct poll_table_struct *pts) -{ - struct wl1273_device *radio =3D video_get_drvdata(video_devdata(file)); - struct wl1273_core *core =3D radio->core; - - if (radio->owner && radio->owner !=3D file) - return EPOLLERR; - - radio->owner =3D file; - - if (core->mode =3D=3D WL1273_MODE_RX) { - poll_wait(file, &radio->read_queue, pts); - - if (radio->rd_index !=3D radio->wr_index) - return EPOLLIN | EPOLLRDNORM; - - } else if (core->mode =3D=3D WL1273_MODE_TX) { - return EPOLLOUT | EPOLLWRNORM; - } - - return 0; -} - -static int wl1273_fm_fops_open(struct file *file) -{ - struct wl1273_device *radio =3D video_get_drvdata(video_devdata(file)); - struct wl1273_core *core =3D radio->core; - int r =3D 0; - - dev_dbg(radio->dev, "%s\n", __func__); - - if (core->mode =3D=3D WL1273_MODE_RX && radio->rds_on && - !radio->rds_users) { - dev_dbg(radio->dev, "%s: Mode: %d\n", __func__, core->mode); - - if (mutex_lock_interruptible(&core->lock)) - return -EINTR; - - radio->irq_flags |=3D WL1273_RDS_EVENT; - - r =3D core->write(core, WL1273_INT_MASK_SET, - radio->irq_flags); - if (r) { - mutex_unlock(&core->lock); - goto out; - } - - radio->rds_users++; - - mutex_unlock(&core->lock); - } -out: - return r; -} - -static int wl1273_fm_fops_release(struct file *file) -{ - struct wl1273_device *radio =3D video_get_drvdata(video_devdata(file)); - struct wl1273_core *core =3D radio->core; - int r =3D 0; - - dev_dbg(radio->dev, "%s\n", __func__); - - if (radio->rds_users > 0) { - radio->rds_users--; - if (radio->rds_users =3D=3D 0) { - mutex_lock(&core->lock); - - radio->irq_flags &=3D ~WL1273_RDS_EVENT; - - if (core->mode =3D=3D WL1273_MODE_RX) { - r =3D core->write(core, - WL1273_INT_MASK_SET, - radio->irq_flags); - if (r) { - mutex_unlock(&core->lock); - goto out; - } - } - mutex_unlock(&core->lock); - } - } - - if (file =3D=3D radio->owner) - radio->owner =3D NULL; -out: - return r; -} - -static ssize_t wl1273_fm_fops_read(struct file *file, char __user *buf, - size_t count, loff_t *ppos) -{ - int r =3D 0; - struct wl1273_device *radio =3D video_get_drvdata(video_devdata(file)); - struct wl1273_core *core =3D radio->core; - unsigned int block_count =3D 0; - u16 val; - - dev_dbg(radio->dev, "%s\n", __func__); - - if (core->mode !=3D WL1273_MODE_RX) - return 0; - - if (radio->rds_users =3D=3D 0) { - dev_warn(radio->dev, "%s: RDS not on.\n", __func__); - return 0; - } - - if (mutex_lock_interruptible(&core->lock)) - return -EINTR; - - /* - * Multiple processes can open the device, but only - * one at a time gets read access. - */ - if (radio->owner && radio->owner !=3D file) { - r =3D -EBUSY; - goto out; - } - radio->owner =3D file; - - r =3D core->read(core, WL1273_RDS_SYNC_GET, &val); - if (r) { - dev_err(radio->dev, "%s: Get RDS_SYNC fails.\n", __func__); - goto out; - } else if (val =3D=3D 0) { - dev_info(radio->dev, "RDS_SYNC: Not synchronized\n"); - r =3D -ENODATA; - goto out; - } - - /* block if no new data available */ - while (radio->wr_index =3D=3D radio->rd_index) { - if (file->f_flags & O_NONBLOCK) { - r =3D -EWOULDBLOCK; - goto out; - } - - dev_dbg(radio->dev, "%s: Wait for RDS data.\n", __func__); - if (wait_event_interruptible(radio->read_queue, - radio->wr_index !=3D - radio->rd_index) < 0) { - r =3D -EINTR; - goto out; - } - } - - /* calculate block count from byte count */ - count /=3D RDS_BLOCK_SIZE; - - /* copy RDS blocks from the internal buffer and to user buffer */ - while (block_count < count) { - if (radio->rd_index =3D=3D radio->wr_index) - break; - - /* always transfer complete RDS blocks */ - if (copy_to_user(buf, &radio->buffer[radio->rd_index], - RDS_BLOCK_SIZE)) - break; - - /* increment and wrap the read pointer */ - radio->rd_index +=3D RDS_BLOCK_SIZE; - if (radio->rd_index >=3D radio->buf_size) - radio->rd_index =3D 0; - - /* increment counters */ - block_count++; - buf +=3D RDS_BLOCK_SIZE; - r +=3D RDS_BLOCK_SIZE; - } - -out: - dev_dbg(radio->dev, "%s: exit\n", __func__); - mutex_unlock(&core->lock); - - return r; -} - -static const struct v4l2_file_operations wl1273_fops =3D { - .owner =3D THIS_MODULE, - .read =3D wl1273_fm_fops_read, - .write =3D wl1273_fm_fops_write, - .poll =3D wl1273_fm_fops_poll, - .unlocked_ioctl =3D video_ioctl2, - .open =3D wl1273_fm_fops_open, - .release =3D wl1273_fm_fops_release, -}; - -static int wl1273_fm_vidioc_querycap(struct file *file, void *priv, - struct v4l2_capability *capability) -{ - struct wl1273_device *radio =3D video_get_drvdata(video_devdata(file)); - - dev_dbg(radio->dev, "%s\n", __func__); - - strscpy(capability->driver, WL1273_FM_DRIVER_NAME, - sizeof(capability->driver)); - strscpy(capability->card, "TI Wl1273 FM Radio", - sizeof(capability->card)); - strscpy(capability->bus_info, radio->bus_type, - sizeof(capability->bus_info)); - return 0; -} - -static int wl1273_fm_vidioc_g_input(struct file *file, void *priv, - unsigned int *i) -{ - struct wl1273_device *radio =3D video_get_drvdata(video_devdata(file)); - - dev_dbg(radio->dev, "%s\n", __func__); - - *i =3D 0; - - return 0; -} - -static int wl1273_fm_vidioc_s_input(struct file *file, void *priv, - unsigned int i) -{ - struct wl1273_device *radio =3D video_get_drvdata(video_devdata(file)); - - dev_dbg(radio->dev, "%s\n", __func__); - - if (i !=3D 0) - return -EINVAL; - - return 0; -} - -/** - * wl1273_fm_set_tx_power() - Set the transmission power value. - * @radio: A pointer to the device struct. - * @power: The new power value. - */ -static int wl1273_fm_set_tx_power(struct wl1273_device *radio, u16 power) -{ - struct wl1273_core *core =3D radio->core; - int r; - - if (core->mode =3D=3D WL1273_MODE_OFF || - core->mode =3D=3D WL1273_MODE_SUSPENDED) - return -EPERM; - - mutex_lock(&core->lock); - - /* Convert the dBuV value to chip presentation */ - r =3D core->write(core, WL1273_POWER_LEV_SET, 122 - power); - if (r) - goto out; - - radio->tx_power =3D power; - -out: - mutex_unlock(&core->lock); - return r; -} - -#define WL1273_SPACING_50kHz 1 -#define WL1273_SPACING_100kHz 2 -#define WL1273_SPACING_200kHz 4 - -static int wl1273_fm_tx_set_spacing(struct wl1273_device *radio, - unsigned int spacing) -{ - struct wl1273_core *core =3D radio->core; - int r; - - if (spacing =3D=3D 0) { - r =3D core->write(core, WL1273_SCAN_SPACING_SET, - WL1273_SPACING_100kHz); - radio->spacing =3D 100; - } else if (spacing - 50000 < 25000) { - r =3D core->write(core, WL1273_SCAN_SPACING_SET, - WL1273_SPACING_50kHz); - radio->spacing =3D 50; - } else if (spacing - 100000 < 50000) { - r =3D core->write(core, WL1273_SCAN_SPACING_SET, - WL1273_SPACING_100kHz); - radio->spacing =3D 100; - } else { - r =3D core->write(core, WL1273_SCAN_SPACING_SET, - WL1273_SPACING_200kHz); - radio->spacing =3D 200; - } - - return r; -} - -static int wl1273_fm_g_volatile_ctrl(struct v4l2_ctrl *ctrl) -{ - struct wl1273_device *radio =3D ctrl->priv; - struct wl1273_core *core =3D radio->core; - - dev_dbg(radio->dev, "%s\n", __func__); - - if (mutex_lock_interruptible(&core->lock)) - return -EINTR; - - switch (ctrl->id) { - case V4L2_CID_TUNE_ANTENNA_CAPACITOR: - ctrl->val =3D wl1273_fm_get_tx_ctune(radio); - break; - - default: - dev_warn(radio->dev, "%s: Unknown IOCTL: %d\n", - __func__, ctrl->id); - break; - } - - mutex_unlock(&core->lock); - - return 0; -} - -#define WL1273_MUTE_SOFT_ENABLE (1 << 0) -#define WL1273_MUTE_AC (1 << 1) -#define WL1273_MUTE_HARD_LEFT (1 << 2) -#define WL1273_MUTE_HARD_RIGHT (1 << 3) -#define WL1273_MUTE_SOFT_FORCE (1 << 4) - -static inline struct wl1273_device *to_radio(struct v4l2_ctrl *ctrl) -{ - return container_of(ctrl->handler, struct wl1273_device, ctrl_handler); -} - -static int wl1273_fm_s_ctrl(struct v4l2_ctrl *ctrl) -{ - struct wl1273_device *radio =3D to_radio(ctrl); - struct wl1273_core *core =3D radio->core; - int r =3D 0; - - dev_dbg(radio->dev, "%s\n", __func__); - - switch (ctrl->id) { - case V4L2_CID_AUDIO_MUTE: - if (mutex_lock_interruptible(&core->lock)) - return -EINTR; - - if (core->mode =3D=3D WL1273_MODE_RX && ctrl->val) - r =3D core->write(core, - WL1273_MUTE_STATUS_SET, - WL1273_MUTE_HARD_LEFT | - WL1273_MUTE_HARD_RIGHT); - else if (core->mode =3D=3D WL1273_MODE_RX) - r =3D core->write(core, - WL1273_MUTE_STATUS_SET, 0x0); - else if (core->mode =3D=3D WL1273_MODE_TX && ctrl->val) - r =3D core->write(core, WL1273_MUTE, 1); - else if (core->mode =3D=3D WL1273_MODE_TX) - r =3D core->write(core, WL1273_MUTE, 0); - - mutex_unlock(&core->lock); - break; - - case V4L2_CID_AUDIO_VOLUME: - if (ctrl->val =3D=3D 0) - r =3D wl1273_fm_set_mode(radio, WL1273_MODE_OFF); - else - r =3D core->set_volume(core, core->volume); - break; - - case V4L2_CID_TUNE_PREEMPHASIS: - r =3D wl1273_fm_set_preemphasis(radio, ctrl->val); - break; - - case V4L2_CID_TUNE_POWER_LEVEL: - r =3D wl1273_fm_set_tx_power(radio, ctrl->val); - break; - - default: - dev_warn(radio->dev, "%s: Unknown IOCTL: %d\n", - __func__, ctrl->id); - break; - } - - dev_dbg(radio->dev, "%s\n", __func__); - return r; -} - -static int wl1273_fm_vidioc_g_audio(struct file *file, void *priv, - struct v4l2_audio *audio) -{ - struct wl1273_device *radio =3D video_get_drvdata(video_devdata(file)); - - dev_dbg(radio->dev, "%s\n", __func__); - - if (audio->index > 1) - return -EINVAL; - - strscpy(audio->name, "Radio", sizeof(audio->name)); - audio->capability =3D V4L2_AUDCAP_STEREO; - - return 0; -} - -static int wl1273_fm_vidioc_s_audio(struct file *file, void *priv, - const struct v4l2_audio *audio) -{ - struct wl1273_device *radio =3D video_get_drvdata(video_devdata(file)); - - dev_dbg(radio->dev, "%s\n", __func__); - - if (audio->index !=3D 0) - return -EINVAL; - - return 0; -} - -#define WL1273_RDS_NOT_SYNCHRONIZED 0 -#define WL1273_RDS_SYNCHRONIZED 1 - -static int wl1273_fm_vidioc_g_tuner(struct file *file, void *priv, - struct v4l2_tuner *tuner) -{ - struct wl1273_device *radio =3D video_get_drvdata(video_devdata(file)); - struct wl1273_core *core =3D radio->core; - u16 val; - int r; - - dev_dbg(radio->dev, "%s\n", __func__); - - if (tuner->index > 0) - return -EINVAL; - - strscpy(tuner->name, WL1273_FM_DRIVER_NAME, sizeof(tuner->name)); - tuner->type =3D V4L2_TUNER_RADIO; - - tuner->rangelow =3D WL1273_FREQ(WL1273_BAND_JAPAN_LOW); - tuner->rangehigh =3D WL1273_FREQ(WL1273_BAND_OTHER_HIGH); - - tuner->capability =3D V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_RDS | - V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS_BLOCK_IO | - V4L2_TUNER_CAP_HWSEEK_BOUNDED | V4L2_TUNER_CAP_HWSEEK_WRAP; - - if (radio->stereo) - tuner->audmode =3D V4L2_TUNER_MODE_STEREO; - else - tuner->audmode =3D V4L2_TUNER_MODE_MONO; - - if (core->mode !=3D WL1273_MODE_RX) - return 0; - - if (mutex_lock_interruptible(&core->lock)) - return -EINTR; - - r =3D core->read(core, WL1273_STEREO_GET, &val); - if (r) - goto out; - - if (val =3D=3D 1) - tuner->rxsubchans =3D V4L2_TUNER_SUB_STEREO; - else - tuner->rxsubchans =3D V4L2_TUNER_SUB_MONO; - - r =3D core->read(core, WL1273_RSSI_LVL_GET, &val); - if (r) - goto out; - - tuner->signal =3D (s16) val; - dev_dbg(radio->dev, "Signal: %d\n", tuner->signal); - - tuner->afc =3D 0; - - r =3D core->read(core, WL1273_RDS_SYNC_GET, &val); - if (r) - goto out; - - if (val =3D=3D WL1273_RDS_SYNCHRONIZED) - tuner->rxsubchans |=3D V4L2_TUNER_SUB_RDS; -out: - mutex_unlock(&core->lock); - - return r; -} - -static int wl1273_fm_vidioc_s_tuner(struct file *file, void *priv, - const struct v4l2_tuner *tuner) -{ - struct wl1273_device *radio =3D video_get_drvdata(video_devdata(file)); - struct wl1273_core *core =3D radio->core; - int r =3D 0; - - dev_dbg(radio->dev, "%s\n", __func__); - dev_dbg(radio->dev, "tuner->index: %d\n", tuner->index); - dev_dbg(radio->dev, "tuner->name: %s\n", tuner->name); - dev_dbg(radio->dev, "tuner->capability: 0x%04x\n", tuner->capability); - dev_dbg(radio->dev, "tuner->rxsubchans: 0x%04x\n", tuner->rxsubchans); - dev_dbg(radio->dev, "tuner->rangelow: %d\n", tuner->rangelow); - dev_dbg(radio->dev, "tuner->rangehigh: %d\n", tuner->rangehigh); - - if (tuner->index > 0) - return -EINVAL; - - if (mutex_lock_interruptible(&core->lock)) - return -EINTR; - - r =3D wl1273_fm_set_mode(radio, WL1273_MODE_RX); - if (r) - goto out; - - if (tuner->rxsubchans & V4L2_TUNER_SUB_RDS) - r =3D wl1273_fm_set_rds(radio, WL1273_RDS_ON); - else - r =3D wl1273_fm_set_rds(radio, WL1273_RDS_OFF); - - if (r) - dev_warn(radio->dev, "%s: RDS fails: %d\n", __func__, r); - - if (tuner->audmode =3D=3D V4L2_TUNER_MODE_MONO) { - r =3D core->write(core, WL1273_MOST_MODE_SET, WL1273_RX_MONO); - if (r < 0) { - dev_warn(radio->dev, "%s: MOST_MODE fails: %d\n", - __func__, r); - goto out; - } - radio->stereo =3D false; - } else if (tuner->audmode =3D=3D V4L2_TUNER_MODE_STEREO) { - r =3D core->write(core, WL1273_MOST_MODE_SET, WL1273_RX_STEREO); - if (r < 0) { - dev_warn(radio->dev, "%s: MOST_MODE fails: %d\n", - __func__, r); - goto out; - } - radio->stereo =3D true; - } else { - dev_err(radio->dev, "%s: tuner->audmode: %d\n", - __func__, tuner->audmode); - r =3D -EINVAL; - goto out; - } - -out: - mutex_unlock(&core->lock); - - return r; -} - -static int wl1273_fm_vidioc_g_frequency(struct file *file, void *priv, - struct v4l2_frequency *freq) -{ - struct wl1273_device *radio =3D video_get_drvdata(video_devdata(file)); - struct wl1273_core *core =3D radio->core; - - dev_dbg(radio->dev, "%s\n", __func__); - - if (mutex_lock_interruptible(&core->lock)) - return -EINTR; - - freq->type =3D V4L2_TUNER_RADIO; - freq->frequency =3D WL1273_FREQ(wl1273_fm_get_freq(radio)); - - mutex_unlock(&core->lock); - - return 0; -} - -static int wl1273_fm_vidioc_s_frequency(struct file *file, void *priv, - const struct v4l2_frequency *freq) -{ - struct wl1273_device *radio =3D video_get_drvdata(video_devdata(file)); - struct wl1273_core *core =3D radio->core; - int r; - - dev_dbg(radio->dev, "%s: %d\n", __func__, freq->frequency); - - if (freq->type !=3D V4L2_TUNER_RADIO) { - dev_dbg(radio->dev, - "freq->type !=3D V4L2_TUNER_RADIO: %d\n", freq->type); - return -EINVAL; - } - - if (mutex_lock_interruptible(&core->lock)) - return -EINTR; - - if (core->mode =3D=3D WL1273_MODE_RX) { - dev_dbg(radio->dev, "freq: %d\n", freq->frequency); - - r =3D wl1273_fm_set_rx_freq(radio, - WL1273_INV_FREQ(freq->frequency)); - if (r) - dev_warn(radio->dev, WL1273_FM_DRIVER_NAME - ": set frequency failed with %d\n", r); - } else { - r =3D wl1273_fm_set_tx_freq(radio, - WL1273_INV_FREQ(freq->frequency)); - if (r) - dev_warn(radio->dev, WL1273_FM_DRIVER_NAME - ": set frequency failed with %d\n", r); - } - - mutex_unlock(&core->lock); - - dev_dbg(radio->dev, "wl1273_vidioc_s_frequency: DONE\n"); - return r; -} - -#define WL1273_DEFAULT_SEEK_LEVEL 7 - -static int wl1273_fm_vidioc_s_hw_freq_seek(struct file *file, void *priv, - const struct v4l2_hw_freq_seek *seek) -{ - struct wl1273_device *radio =3D video_get_drvdata(video_devdata(file)); - struct wl1273_core *core =3D radio->core; - int r; - - dev_dbg(radio->dev, "%s\n", __func__); - - if (seek->tuner !=3D 0 || seek->type !=3D V4L2_TUNER_RADIO) - return -EINVAL; - - if (file->f_flags & O_NONBLOCK) - return -EWOULDBLOCK; - - if (mutex_lock_interruptible(&core->lock)) - return -EINTR; - - r =3D wl1273_fm_set_mode(radio, WL1273_MODE_RX); - if (r) - goto out; - - r =3D wl1273_fm_tx_set_spacing(radio, seek->spacing); - if (r) - dev_warn(radio->dev, "HW seek failed: %d\n", r); - - r =3D wl1273_fm_set_seek(radio, seek->wrap_around, seek->seek_upward, - WL1273_DEFAULT_SEEK_LEVEL); - if (r) - dev_warn(radio->dev, "HW seek failed: %d\n", r); - -out: - mutex_unlock(&core->lock); - return r; -} - -static int wl1273_fm_vidioc_s_modulator(struct file *file, void *priv, - const struct v4l2_modulator *modulator) -{ - struct wl1273_device *radio =3D video_get_drvdata(video_devdata(file)); - struct wl1273_core *core =3D radio->core; - int r =3D 0; - - dev_dbg(radio->dev, "%s\n", __func__); - - if (modulator->index > 0) - return -EINVAL; - - if (mutex_lock_interruptible(&core->lock)) - return -EINTR; - - r =3D wl1273_fm_set_mode(radio, WL1273_MODE_TX); - if (r) - goto out; - - if (modulator->txsubchans & V4L2_TUNER_SUB_RDS) - r =3D wl1273_fm_set_rds(radio, WL1273_RDS_ON); - else - r =3D wl1273_fm_set_rds(radio, WL1273_RDS_OFF); - - if (modulator->txsubchans & V4L2_TUNER_SUB_MONO) - r =3D core->write(core, WL1273_MONO_SET, WL1273_TX_MONO); - else - r =3D core->write(core, WL1273_MONO_SET, - WL1273_RX_STEREO); - if (r < 0) - dev_warn(radio->dev, WL1273_FM_DRIVER_NAME - "MONO_SET fails: %d\n", r); -out: - mutex_unlock(&core->lock); - - return r; -} - -static int wl1273_fm_vidioc_g_modulator(struct file *file, void *priv, - struct v4l2_modulator *modulator) -{ - struct wl1273_device *radio =3D video_get_drvdata(video_devdata(file)); - struct wl1273_core *core =3D radio->core; - u16 val; - int r; - - dev_dbg(radio->dev, "%s\n", __func__); - - strscpy(modulator->name, WL1273_FM_DRIVER_NAME, - sizeof(modulator->name)); - - modulator->rangelow =3D WL1273_FREQ(WL1273_BAND_JAPAN_LOW); - modulator->rangehigh =3D WL1273_FREQ(WL1273_BAND_OTHER_HIGH); - - modulator->capability =3D V4L2_TUNER_CAP_LOW | V4L2_TUNER_CAP_RDS | - V4L2_TUNER_CAP_STEREO | V4L2_TUNER_CAP_RDS_BLOCK_IO; - - if (core->mode !=3D WL1273_MODE_TX) - return 0; - - if (mutex_lock_interruptible(&core->lock)) - return -EINTR; - - r =3D core->read(core, WL1273_MONO_SET, &val); - if (r) - goto out; - - if (val =3D=3D WL1273_TX_STEREO) - modulator->txsubchans =3D V4L2_TUNER_SUB_STEREO; - else - modulator->txsubchans =3D V4L2_TUNER_SUB_MONO; - - if (radio->rds_on) - modulator->txsubchans |=3D V4L2_TUNER_SUB_RDS; -out: - mutex_unlock(&core->lock); - - return 0; -} - -static int wl1273_fm_vidioc_log_status(struct file *file, void *priv) -{ - struct wl1273_device *radio =3D video_get_drvdata(video_devdata(file)); - struct wl1273_core *core =3D radio->core; - struct device *dev =3D radio->dev; - u16 val; - int r; - - dev_info(dev, DRIVER_DESC); - - if (core->mode =3D=3D WL1273_MODE_OFF) { - dev_info(dev, "Mode: Off\n"); - return 0; - } - - if (core->mode =3D=3D WL1273_MODE_SUSPENDED) { - dev_info(dev, "Mode: Suspended\n"); - return 0; - } - - r =3D core->read(core, WL1273_ASIC_ID_GET, &val); - if (r) - dev_err(dev, "%s: Get ASIC_ID fails.\n", __func__); - else - dev_info(dev, "ASIC_ID: 0x%04x\n", val); - - r =3D core->read(core, WL1273_ASIC_VER_GET, &val); - if (r) - dev_err(dev, "%s: Get ASIC_VER fails.\n", __func__); - else - dev_info(dev, "ASIC Version: 0x%04x\n", val); - - r =3D core->read(core, WL1273_FIRM_VER_GET, &val); - if (r) - dev_err(dev, "%s: Get FIRM_VER fails.\n", __func__); - else - dev_info(dev, "FW version: %d(0x%04x)\n", val, val); - - r =3D core->read(core, WL1273_BAND_SET, &val); - if (r) - dev_err(dev, "%s: Get BAND fails.\n", __func__); - else - dev_info(dev, "BAND: %d\n", val); - - if (core->mode =3D=3D WL1273_MODE_TX) { - r =3D core->read(core, WL1273_PUPD_SET, &val); - if (r) - dev_err(dev, "%s: Get PUPD fails.\n", __func__); - else - dev_info(dev, "PUPD: 0x%04x\n", val); - - r =3D core->read(core, WL1273_CHANL_SET, &val); - if (r) - dev_err(dev, "%s: Get CHANL fails.\n", __func__); - else - dev_info(dev, "Tx frequency: %dkHz\n", val*10); - } else if (core->mode =3D=3D WL1273_MODE_RX) { - int bf =3D radio->rangelow; - - r =3D core->read(core, WL1273_FREQ_SET, &val); - if (r) - dev_err(dev, "%s: Get FREQ fails.\n", __func__); - else - dev_info(dev, "RX Frequency: %dkHz\n", bf + val*50); - - r =3D core->read(core, WL1273_MOST_MODE_SET, &val); - if (r) - dev_err(dev, "%s: Get MOST_MODE fails.\n", - __func__); - else if (val =3D=3D 0) - dev_info(dev, "MOST_MODE: Stereo according to blend\n"); - else if (val =3D=3D 1) - dev_info(dev, "MOST_MODE: Force mono output\n"); - else - dev_info(dev, "MOST_MODE: Unexpected value: %d\n", val); - - r =3D core->read(core, WL1273_MOST_BLEND_SET, &val); - if (r) - dev_err(dev, "%s: Get MOST_BLEND fails.\n", __func__); - else if (val =3D=3D 0) - dev_info(dev, - "MOST_BLEND: Switched blend & hysteresis.\n"); - else if (val =3D=3D 1) - dev_info(dev, "MOST_BLEND: Soft blend.\n"); - else - dev_info(dev, "MOST_BLEND: Unexpected val: %d\n", val); - - r =3D core->read(core, WL1273_STEREO_GET, &val); - if (r) - dev_err(dev, "%s: Get STEREO fails.\n", __func__); - else if (val =3D=3D 0) - dev_info(dev, "STEREO: Not detected\n"); - else if (val =3D=3D 1) - dev_info(dev, "STEREO: Detected\n"); - else - dev_info(dev, "STEREO: Unexpected value: %d\n", val); - - r =3D core->read(core, WL1273_RSSI_LVL_GET, &val); - if (r) - dev_err(dev, "%s: Get RSSI_LVL fails.\n", __func__); - else - dev_info(dev, "RX signal strength: %d\n", (s16) val); - - r =3D core->read(core, WL1273_POWER_SET, &val); - if (r) - dev_err(dev, "%s: Get POWER fails.\n", __func__); - else - dev_info(dev, "POWER: 0x%04x\n", val); - - r =3D core->read(core, WL1273_INT_MASK_SET, &val); - if (r) - dev_err(dev, "%s: Get INT_MASK fails.\n", __func__); - else - dev_info(dev, "INT_MASK: 0x%04x\n", val); - - r =3D core->read(core, WL1273_RDS_SYNC_GET, &val); - if (r) - dev_err(dev, "%s: Get RDS_SYNC fails.\n", - __func__); - else if (val =3D=3D 0) - dev_info(dev, "RDS_SYNC: Not synchronized\n"); - - else if (val =3D=3D 1) - dev_info(dev, "RDS_SYNC: Synchronized\n"); - else - dev_info(dev, "RDS_SYNC: Unexpected value: %d\n", val); - - r =3D core->read(core, WL1273_I2S_MODE_CONFIG_SET, &val); - if (r) - dev_err(dev, "%s: Get I2S_MODE_CONFIG fails.\n", - __func__); - else - dev_info(dev, "I2S_MODE_CONFIG: 0x%04x\n", val); - - r =3D core->read(core, WL1273_VOLUME_SET, &val); - if (r) - dev_err(dev, "%s: Get VOLUME fails.\n", __func__); - else - dev_info(dev, "VOLUME: 0x%04x\n", val); - } - - return 0; -} - -static void wl1273_vdev_release(struct video_device *dev) -{ -} - -static const struct v4l2_ctrl_ops wl1273_ctrl_ops =3D { - .s_ctrl =3D wl1273_fm_s_ctrl, - .g_volatile_ctrl =3D wl1273_fm_g_volatile_ctrl, -}; - -static const struct v4l2_ioctl_ops wl1273_ioctl_ops =3D { - .vidioc_querycap =3D wl1273_fm_vidioc_querycap, - .vidioc_g_input =3D wl1273_fm_vidioc_g_input, - .vidioc_s_input =3D wl1273_fm_vidioc_s_input, - .vidioc_g_audio =3D wl1273_fm_vidioc_g_audio, - .vidioc_s_audio =3D wl1273_fm_vidioc_s_audio, - .vidioc_g_tuner =3D wl1273_fm_vidioc_g_tuner, - .vidioc_s_tuner =3D wl1273_fm_vidioc_s_tuner, - .vidioc_g_frequency =3D wl1273_fm_vidioc_g_frequency, - .vidioc_s_frequency =3D wl1273_fm_vidioc_s_frequency, - .vidioc_s_hw_freq_seek =3D wl1273_fm_vidioc_s_hw_freq_seek, - .vidioc_g_modulator =3D wl1273_fm_vidioc_g_modulator, - .vidioc_s_modulator =3D wl1273_fm_vidioc_s_modulator, - .vidioc_log_status =3D wl1273_fm_vidioc_log_status, -}; - -static const struct video_device wl1273_viddev_template =3D { - .fops =3D &wl1273_fops, - .ioctl_ops =3D &wl1273_ioctl_ops, - .name =3D WL1273_FM_DRIVER_NAME, - .release =3D wl1273_vdev_release, - .vfl_dir =3D VFL_DIR_TX, - .device_caps =3D V4L2_CAP_HW_FREQ_SEEK | V4L2_CAP_TUNER | - V4L2_CAP_RADIO | V4L2_CAP_AUDIO | - V4L2_CAP_RDS_CAPTURE | V4L2_CAP_MODULATOR | - V4L2_CAP_RDS_OUTPUT, -}; - -static void wl1273_fm_radio_remove(struct platform_device *pdev) -{ - struct wl1273_device *radio =3D platform_get_drvdata(pdev); - struct wl1273_core *core =3D radio->core; - - dev_info(&pdev->dev, "%s.\n", __func__); - - free_irq(core->client->irq, radio); - core->pdata->free_resources(); - - v4l2_ctrl_handler_free(&radio->ctrl_handler); - video_unregister_device(&radio->videodev); - v4l2_device_unregister(&radio->v4l2dev); -} - -static int wl1273_fm_radio_probe(struct platform_device *pdev) -{ - struct wl1273_core **core =3D pdev->dev.platform_data; - struct wl1273_device *radio; - struct v4l2_ctrl *ctrl; - int r =3D 0; - - pr_debug("%s\n", __func__); - - if (!core) { - dev_err(&pdev->dev, "No platform data.\n"); - r =3D -EINVAL; - goto pdata_err; - } - - radio =3D devm_kzalloc(&pdev->dev, sizeof(*radio), GFP_KERNEL); - if (!radio) { - r =3D -ENOMEM; - goto pdata_err; - } - - /* RDS buffer allocation */ - radio->buf_size =3D rds_buf * RDS_BLOCK_SIZE; - radio->buffer =3D devm_kzalloc(&pdev->dev, radio->buf_size, GFP_KERNEL); - if (!radio->buffer) { - pr_err("Cannot allocate memory for RDS buffer.\n"); - r =3D -ENOMEM; - goto pdata_err; - } - - radio->core =3D *core; - radio->irq_flags =3D WL1273_IRQ_MASK; - radio->dev =3D &radio->core->client->dev; - radio->rds_on =3D false; - radio->core->mode =3D WL1273_MODE_OFF; - radio->tx_power =3D 118; - radio->core->audio_mode =3D WL1273_AUDIO_ANALOG; - radio->band =3D WL1273_BAND_OTHER; - radio->core->i2s_mode =3D WL1273_I2S_DEF_MODE; - radio->core->channel_number =3D 2; - radio->core->volume =3D WL1273_DEFAULT_VOLUME; - radio->rx_frequency =3D WL1273_BAND_OTHER_LOW; - radio->tx_frequency =3D WL1273_BAND_OTHER_HIGH; - radio->rangelow =3D WL1273_BAND_OTHER_LOW; - radio->rangehigh =3D WL1273_BAND_OTHER_HIGH; - radio->stereo =3D true; - radio->bus_type =3D "I2C"; - - if (radio->core->pdata->request_resources) { - r =3D radio->core->pdata->request_resources(radio->core->client); - if (r) { - dev_err(radio->dev, WL1273_FM_DRIVER_NAME - ": Cannot get platform data\n"); - goto pdata_err; - } - - dev_dbg(radio->dev, "irq: %d\n", radio->core->client->irq); - - r =3D request_threaded_irq(radio->core->client->irq, NULL, - wl1273_fm_irq_thread_handler, - IRQF_ONESHOT | IRQF_TRIGGER_FALLING, - "wl1273-fm", radio); - if (r < 0) { - dev_err(radio->dev, WL1273_FM_DRIVER_NAME - ": Unable to register IRQ handler: %d\n", r); - goto err_request_irq; - } - } else { - dev_err(radio->dev, WL1273_FM_DRIVER_NAME ": Core WL1273 IRQ not configu= red"); - r =3D -EINVAL; - goto pdata_err; - } - - init_completion(&radio->busy); - init_waitqueue_head(&radio->read_queue); - - radio->write_buf =3D devm_kzalloc(&pdev->dev, 256, GFP_KERNEL); - if (!radio->write_buf) { - r =3D -ENOMEM; - goto write_buf_err; - } - - radio->dev =3D &pdev->dev; - radio->v4l2dev.ctrl_handler =3D &radio->ctrl_handler; - radio->rds_users =3D 0; - - r =3D v4l2_device_register(&pdev->dev, &radio->v4l2dev); - if (r) { - dev_err(&pdev->dev, "Cannot register v4l2_device.\n"); - goto write_buf_err; - } - - /* V4L2 configuration */ - radio->videodev =3D wl1273_viddev_template; - - radio->videodev.v4l2_dev =3D &radio->v4l2dev; - - v4l2_ctrl_handler_init(&radio->ctrl_handler, 6); - - /* add in ascending ID order */ - v4l2_ctrl_new_std(&radio->ctrl_handler, &wl1273_ctrl_ops, - V4L2_CID_AUDIO_VOLUME, 0, WL1273_MAX_VOLUME, 1, - WL1273_DEFAULT_VOLUME); - - v4l2_ctrl_new_std(&radio->ctrl_handler, &wl1273_ctrl_ops, - V4L2_CID_AUDIO_MUTE, 0, 1, 1, 1); - - v4l2_ctrl_new_std_menu(&radio->ctrl_handler, &wl1273_ctrl_ops, - V4L2_CID_TUNE_PREEMPHASIS, - V4L2_PREEMPHASIS_75_uS, 0x03, - V4L2_PREEMPHASIS_50_uS); - - v4l2_ctrl_new_std(&radio->ctrl_handler, &wl1273_ctrl_ops, - V4L2_CID_TUNE_POWER_LEVEL, 91, 122, 1, 118); - - ctrl =3D v4l2_ctrl_new_std(&radio->ctrl_handler, &wl1273_ctrl_ops, - V4L2_CID_TUNE_ANTENNA_CAPACITOR, - 0, 255, 1, 255); - if (ctrl) - ctrl->flags |=3D V4L2_CTRL_FLAG_VOLATILE; - - if (radio->ctrl_handler.error) { - r =3D radio->ctrl_handler.error; - dev_err(&pdev->dev, "Ctrl handler error: %d\n", r); - goto handler_init_err; - } - - video_set_drvdata(&radio->videodev, radio); - platform_set_drvdata(pdev, radio); - - /* register video device */ - r =3D video_register_device(&radio->videodev, VFL_TYPE_RADIO, radio_nr); - if (r) { - dev_err(&pdev->dev, WL1273_FM_DRIVER_NAME - ": Could not register video device\n"); - goto handler_init_err; - } - - return 0; - -handler_init_err: - v4l2_ctrl_handler_free(&radio->ctrl_handler); - v4l2_device_unregister(&radio->v4l2dev); -write_buf_err: - free_irq(radio->core->client->irq, radio); -err_request_irq: - radio->core->pdata->free_resources(); -pdata_err: - return r; -} - -static struct platform_driver wl1273_fm_radio_driver =3D { - .probe =3D wl1273_fm_radio_probe, - .remove =3D wl1273_fm_radio_remove, - .driver =3D { - .name =3D "wl1273_fm_radio", - }, -}; - -module_platform_driver(wl1273_fm_radio_driver); - -MODULE_AUTHOR("Matti Aaltonen "); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); -MODULE_ALIAS("platform:wl1273_fm_radio"); --=20 2.49.0 From nobody Mon Dec 15 21:27:08 2025 Received: from mx.treblig.org (mx.treblig.org [46.235.229.95]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C48F7263F40; Wed, 25 Jun 2025 13:33:43 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=46.235.229.95 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750858428; cv=none; b=vGorUgN0YO5W+HhoEGT9zJI1ImB+hYz5P5oELhsv2A5XA6rY31qmkmVWgWxqZkBG2QgmvPdnrDbzjn2Sx/XnDuywEWemX74iCjcDluzvJ7j76/5R/R9UJg0dHKLX6iXO9txRaIoKNBJCyJgABXF4/0Yr3O1swsC0534arIpypCI= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750858428; c=relaxed/simple; bh=3J1JIo1jTPjeIOvEE8t5RI90gWubN0eok4h+IXepZqc=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=aKLW8ky5dFH50zrZll5wefmiNjxXPPCWQfs2vX0mYDEMUIXFjEhomZ12jkSodXVO6XDUhfIm/rNDZQVoqxLp3TIACHlWk85Nhdq76guVzt/nDOPt1y2AmsZOoM8vyoj0N4C8DNlSbqb7xN0DdOLyxWa1eFRx/qpHG2gF53uxXwM= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=treblig.org; spf=pass smtp.mailfrom=treblig.org; dkim=pass (2048-bit key) header.d=treblig.org header.i=@treblig.org header.b=sHCgC1SH; arc=none smtp.client-ip=46.235.229.95 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=treblig.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=treblig.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=treblig.org header.i=@treblig.org header.b="sHCgC1SH" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=treblig.org ; s=bytemarkmx; h=MIME-Version:Message-ID:Date:Subject:From:Content-Type:From :Subject; bh=zHLBQp9c3phSjjriwnIQ9WfwFCetptzAuvhLYaTqXe8=; b=sHCgC1SHYFrvNaAX 3tDKvk5kDABXF30APg7rYv3Ch/aSPPciahm4ZVhRci2RMvHMUei6C2dNviSHjacEyQhp5z+fYi8Ut emcZPFg8/+PFPjYlwjfEPmEPe2qe8EoNyzv/Tn/1TxcCxe5cDN9U5UDDnlxvF8mIYvE2q2Puu6ujS V6J8eBkVmT28KjZ+3N9ewEMUbfyVFoHw+/UsJJt1C99EdnUxF2e3N5LrhHc8GwDogD9l6lkoP+MlP kfjgNkQ8Yvl1TFmnSDumLTF+7UqQoFkeM+CyHfhGlo5oXmVb7WBziuZICTlQ095nBMUCEMJOiWI+H gt33AvmwngosozchCw==; Received: from localhost ([127.0.0.1] helo=dalek.home.treblig.org) by mx.treblig.org with esmtp (Exim 4.96) (envelope-from ) id 1uUQFs-00Bvly-0J; Wed, 25 Jun 2025 13:33:36 +0000 From: linux@treblig.org To: arnd@arndb.de, lee@kernel.org, mchehab@kernel.org, lgirdwood@gmail.com, broonie@kernel.org, perex@perex.cz, tiwai@suse.com Cc: linux-media@vger.kernel.org, linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org, "Dr. David Alan Gilbert" Subject: [PATCH 2/4] ASoC: wl1273: Remove Date: Wed, 25 Jun 2025 14:32:56 +0100 Message-ID: <20250625133258.78133-3-linux@treblig.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250625133258.78133-1-linux@treblig.org> References: <20250625133258.78133-1-linux@treblig.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: "Dr. David Alan Gilbert" The wl1273 FM radio is on Arnd's unused driver list: https://lore.kernel.org/lkml/a15bb180-401d-49ad-a212-0c81d613fbc8@app.fas= tmail.com/ Remove the codec component. Signed-off-by: Dr. David Alan Gilbert Acked-by: Arnd Bergmann Acked-by: Mark Brown --- sound/soc/codecs/Kconfig | 4 - sound/soc/codecs/Makefile | 4 +- sound/soc/codecs/wl1273.c | 500 -------------------------------------- sound/soc/codecs/wl1273.h | 16 -- 4 files changed, 1 insertion(+), 523 deletions(-) delete mode 100644 sound/soc/codecs/wl1273.c delete mode 100644 sound/soc/codecs/wl1273.h diff --git a/sound/soc/codecs/Kconfig b/sound/soc/codecs/Kconfig index 126f897312d4..0dbcda013a9d 100644 --- a/sound/soc/codecs/Kconfig +++ b/sound/soc/codecs/Kconfig @@ -302,7 +302,6 @@ config SND_SOC_ALL_CODECS imply SND_SOC_LPASS_MACRO_COMMON imply SND_SOC_LPASS_RX_MACRO imply SND_SOC_LPASS_TX_MACRO - imply SND_SOC_WL1273 imply SND_SOC_WM0010 imply SND_SOC_WM1250_EV1 imply SND_SOC_WM2000 @@ -2310,9 +2309,6 @@ config SND_SOC_WCD939X_SDW The WCD9390/9395 is a audio codec IC Integrated in Qualcomm SoCs like SM8650. =20 -config SND_SOC_WL1273 - tristate - config SND_SOC_WM0010 tristate depends on SPI_MASTER diff --git a/sound/soc/codecs/Makefile b/sound/soc/codecs/Makefile index 6d7aa109ede7..8ba43f224d47 100644 --- a/sound/soc/codecs/Makefile +++ b/sound/soc/codecs/Makefile @@ -347,7 +347,6 @@ snd-soc-wcd938x-y :=3D wcd938x.o snd-soc-wcd938x-sdw-y :=3D wcd938x-sdw.o snd-soc-wcd939x-y :=3D wcd939x.o snd-soc-wcd939x-sdw-y :=3D wcd939x-sdw.o -snd-soc-wl1273-y :=3D wl1273.o snd-soc-wm-adsp-y :=3D wm_adsp.o snd-soc-wm0010-y :=3D wm0010.o snd-soc-wm1250-ev1-y :=3D wm1250-ev1.o @@ -777,7 +776,6 @@ ifdef CONFIG_SND_SOC_WCD939X_SDW # avoid link failure by forcing sdw code built-in when needed obj-$(CONFIG_SND_SOC_WCD939X) +=3D snd-soc-wcd939x-sdw.o endif -obj-$(CONFIG_SND_SOC_WL1273) +=3D snd-soc-wl1273.o obj-$(CONFIG_SND_SOC_WM0010) +=3D snd-soc-wm0010.o obj-$(CONFIG_SND_SOC_WM1250_EV1) +=3D snd-soc-wm1250-ev1.o obj-$(CONFIG_SND_SOC_WM2000) +=3D snd-soc-wm2000.o @@ -853,4 +851,4 @@ obj-$(CONFIG_SND_SOC_LPASS_RX_MACRO) +=3D snd-soc-lpass= -rx-macro.o obj-$(CONFIG_SND_SOC_LPASS_TX_MACRO) +=3D snd-soc-lpass-tx-macro.o =20 # Mux -obj-$(CONFIG_SND_SOC_SIMPLE_MUX) +=3D snd-soc-simple-mux.o \ No newline at end of file +obj-$(CONFIG_SND_SOC_SIMPLE_MUX) +=3D snd-soc-simple-mux.o diff --git a/sound/soc/codecs/wl1273.c b/sound/soc/codecs/wl1273.c deleted file mode 100644 index 737ca82cf976..000000000000 --- a/sound/soc/codecs/wl1273.c +++ /dev/null @@ -1,500 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * ALSA SoC WL1273 codec driver - * - * Author: Matti Aaltonen, - * - * Copyright: (C) 2010, 2011 Nokia Corporation - */ - -#include -#include -#include -#include -#include -#include -#include - -#include "wl1273.h" - -enum wl1273_mode { WL1273_MODE_BT, WL1273_MODE_FM_RX, WL1273_MODE_FM_TX }; - -/* codec private data */ -struct wl1273_priv { - enum wl1273_mode mode; - struct wl1273_core *core; - unsigned int channels; -}; - -static int snd_wl1273_fm_set_i2s_mode(struct wl1273_core *core, - int rate, int width) -{ - struct device *dev =3D &core->client->dev; - int r =3D 0; - u16 mode; - - dev_dbg(dev, "rate: %d\n", rate); - dev_dbg(dev, "width: %d\n", width); - - mutex_lock(&core->lock); - - mode =3D core->i2s_mode & ~WL1273_IS2_WIDTH & ~WL1273_IS2_RATE; - - switch (rate) { - case 48000: - mode |=3D WL1273_IS2_RATE_48K; - break; - case 44100: - mode |=3D WL1273_IS2_RATE_44_1K; - break; - case 32000: - mode |=3D WL1273_IS2_RATE_32K; - break; - case 22050: - mode |=3D WL1273_IS2_RATE_22_05K; - break; - case 16000: - mode |=3D WL1273_IS2_RATE_16K; - break; - case 12000: - mode |=3D WL1273_IS2_RATE_12K; - break; - case 11025: - mode |=3D WL1273_IS2_RATE_11_025; - break; - case 8000: - mode |=3D WL1273_IS2_RATE_8K; - break; - default: - dev_err(dev, "Sampling rate: %d not supported\n", rate); - r =3D -EINVAL; - goto out; - } - - switch (width) { - case 16: - mode |=3D WL1273_IS2_WIDTH_32; - break; - case 20: - mode |=3D WL1273_IS2_WIDTH_40; - break; - case 24: - mode |=3D WL1273_IS2_WIDTH_48; - break; - case 25: - mode |=3D WL1273_IS2_WIDTH_50; - break; - case 30: - mode |=3D WL1273_IS2_WIDTH_60; - break; - case 32: - mode |=3D WL1273_IS2_WIDTH_64; - break; - case 40: - mode |=3D WL1273_IS2_WIDTH_80; - break; - case 48: - mode |=3D WL1273_IS2_WIDTH_96; - break; - case 64: - mode |=3D WL1273_IS2_WIDTH_128; - break; - default: - dev_err(dev, "Data width: %d not supported\n", width); - r =3D -EINVAL; - goto out; - } - - dev_dbg(dev, "WL1273_I2S_DEF_MODE: 0x%04x\n", WL1273_I2S_DEF_MODE); - dev_dbg(dev, "core->i2s_mode: 0x%04x\n", core->i2s_mode); - dev_dbg(dev, "mode: 0x%04x\n", mode); - - if (core->i2s_mode !=3D mode) { - r =3D core->write(core, WL1273_I2S_MODE_CONFIG_SET, mode); - if (r) - goto out; - - core->i2s_mode =3D mode; - r =3D core->write(core, WL1273_AUDIO_ENABLE, - WL1273_AUDIO_ENABLE_I2S); - if (r) - goto out; - } -out: - mutex_unlock(&core->lock); - - return r; -} - -static int snd_wl1273_fm_set_channel_number(struct wl1273_core *core, - int channel_number) -{ - struct device *dev =3D &core->client->dev; - int r =3D 0; - - dev_dbg(dev, "%s\n", __func__); - - mutex_lock(&core->lock); - - if (core->channel_number =3D=3D channel_number) - goto out; - - if (channel_number =3D=3D 1 && core->mode =3D=3D WL1273_MODE_RX) - r =3D core->write(core, WL1273_MOST_MODE_SET, WL1273_RX_MONO); - else if (channel_number =3D=3D 1 && core->mode =3D=3D WL1273_MODE_TX) - r =3D core->write(core, WL1273_MONO_SET, WL1273_TX_MONO); - else if (channel_number =3D=3D 2 && core->mode =3D=3D WL1273_MODE_RX) - r =3D core->write(core, WL1273_MOST_MODE_SET, WL1273_RX_STEREO); - else if (channel_number =3D=3D 2 && core->mode =3D=3D WL1273_MODE_TX) - r =3D core->write(core, WL1273_MONO_SET, WL1273_TX_STEREO); - else - r =3D -EINVAL; -out: - mutex_unlock(&core->lock); - - return r; -} - -static int snd_wl1273_get_audio_route(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component =3D snd_soc_kcontrol_component(kcontr= ol); - struct wl1273_priv *wl1273 =3D snd_soc_component_get_drvdata(component); - - ucontrol->value.enumerated.item[0] =3D wl1273->mode; - - return 0; -} - -/* - * TODO: Implement the audio routing in the driver. Now this control - * only indicates the setting that has been done elsewhere (in the user - * space). - */ -static const char * const wl1273_audio_route[] =3D { "Bt", "FmRx", "FmTx" = }; - -static int snd_wl1273_set_audio_route(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component =3D snd_soc_kcontrol_component(kcontr= ol); - struct wl1273_priv *wl1273 =3D snd_soc_component_get_drvdata(component); - - if (wl1273->mode =3D=3D ucontrol->value.enumerated.item[0]) - return 0; - - /* Do not allow changes while stream is running */ - if (snd_soc_component_active(component)) - return -EPERM; - - if (ucontrol->value.enumerated.item[0] >=3D ARRAY_SIZE(wl1273_audio_rout= e)) - return -EINVAL; - - wl1273->mode =3D ucontrol->value.enumerated.item[0]; - - return 1; -} - -static SOC_ENUM_SINGLE_EXT_DECL(wl1273_enum, wl1273_audio_route); - -static int snd_wl1273_fm_audio_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component =3D snd_soc_kcontrol_component(kcontr= ol); - struct wl1273_priv *wl1273 =3D snd_soc_component_get_drvdata(component); - - dev_dbg(component->dev, "%s: enter.\n", __func__); - - ucontrol->value.enumerated.item[0] =3D wl1273->core->audio_mode; - - return 0; -} - -static int snd_wl1273_fm_audio_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component =3D snd_soc_kcontrol_component(kcontr= ol); - struct wl1273_priv *wl1273 =3D snd_soc_component_get_drvdata(component); - int val, r =3D 0; - - dev_dbg(component->dev, "%s: enter.\n", __func__); - - val =3D ucontrol->value.enumerated.item[0]; - if (wl1273->core->audio_mode =3D=3D val) - return 0; - - r =3D wl1273->core->set_audio(wl1273->core, val); - if (r < 0) - return r; - - return 1; -} - -static const char * const wl1273_audio_strings[] =3D { "Digital", "Analog"= }; - -static SOC_ENUM_SINGLE_EXT_DECL(wl1273_audio_enum, wl1273_audio_strings); - -static int snd_wl1273_fm_volume_get(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component =3D snd_soc_kcontrol_component(kcontr= ol); - struct wl1273_priv *wl1273 =3D snd_soc_component_get_drvdata(component); - - dev_dbg(component->dev, "%s: enter.\n", __func__); - - ucontrol->value.integer.value[0] =3D wl1273->core->volume; - - return 0; -} - -static int snd_wl1273_fm_volume_put(struct snd_kcontrol *kcontrol, - struct snd_ctl_elem_value *ucontrol) -{ - struct snd_soc_component *component =3D snd_soc_kcontrol_component(kcontr= ol); - struct wl1273_priv *wl1273 =3D snd_soc_component_get_drvdata(component); - int r; - - dev_dbg(component->dev, "%s: enter.\n", __func__); - - r =3D wl1273->core->set_volume(wl1273->core, - ucontrol->value.integer.value[0]); - if (r) - return r; - - return 1; -} - -static const struct snd_kcontrol_new wl1273_controls[] =3D { - SOC_ENUM_EXT("Codec Mode", wl1273_enum, - snd_wl1273_get_audio_route, snd_wl1273_set_audio_route), - SOC_ENUM_EXT("Audio Switch", wl1273_audio_enum, - snd_wl1273_fm_audio_get, snd_wl1273_fm_audio_put), - SOC_SINGLE_EXT("Volume", 0, 0, WL1273_MAX_VOLUME, 0, - snd_wl1273_fm_volume_get, snd_wl1273_fm_volume_put), -}; - -static const struct snd_soc_dapm_widget wl1273_dapm_widgets[] =3D { - SND_SOC_DAPM_INPUT("RX"), - - SND_SOC_DAPM_OUTPUT("TX"), -}; - -static const struct snd_soc_dapm_route wl1273_dapm_routes[] =3D { - { "Capture", NULL, "RX" }, - - { "TX", NULL, "Playback" }, -}; - -static int wl1273_startup(struct snd_pcm_substream *substream, - struct snd_soc_dai *dai) -{ - struct snd_soc_component *component =3D dai->component; - struct wl1273_priv *wl1273 =3D snd_soc_component_get_drvdata(component); - - switch (wl1273->mode) { - case WL1273_MODE_BT: - snd_pcm_hw_constraint_single(substream->runtime, - SNDRV_PCM_HW_PARAM_RATE, 8000); - snd_pcm_hw_constraint_single(substream->runtime, - SNDRV_PCM_HW_PARAM_CHANNELS, 1); - break; - case WL1273_MODE_FM_RX: - if (substream->stream =3D=3D SNDRV_PCM_STREAM_PLAYBACK) { - pr_err("Cannot play in RX mode.\n"); - return -EINVAL; - } - break; - case WL1273_MODE_FM_TX: - if (substream->stream =3D=3D SNDRV_PCM_STREAM_CAPTURE) { - pr_err("Cannot capture in TX mode.\n"); - return -EINVAL; - } - break; - default: - return -EINVAL; - } - - return 0; -} - -static int wl1273_hw_params(struct snd_pcm_substream *substream, - struct snd_pcm_hw_params *params, - struct snd_soc_dai *dai) -{ - struct wl1273_priv *wl1273 =3D snd_soc_component_get_drvdata(dai->compone= nt); - struct wl1273_core *core =3D wl1273->core; - unsigned int rate, width, r; - - if (params_width(params) !=3D 16) { - dev_err(dai->dev, "%d bits/sample not supported\n", - params_width(params)); - return -EINVAL; - } - - rate =3D params_rate(params); - width =3D hw_param_interval(params, SNDRV_PCM_HW_PARAM_SAMPLE_BITS)->min; - - if (wl1273->mode =3D=3D WL1273_MODE_BT) { - if (rate !=3D 8000) { - pr_err("Rate %d not supported.\n", params_rate(params)); - return -EINVAL; - } - - if (params_channels(params) !=3D 1) { - pr_err("Only mono supported.\n"); - return -EINVAL; - } - - return 0; - } - - if (wl1273->mode =3D=3D WL1273_MODE_FM_TX && - substream->stream =3D=3D SNDRV_PCM_STREAM_CAPTURE) { - pr_err("Only playback supported with TX.\n"); - return -EINVAL; - } - - if (wl1273->mode =3D=3D WL1273_MODE_FM_RX && - substream->stream =3D=3D SNDRV_PCM_STREAM_PLAYBACK) { - pr_err("Only capture supported with RX.\n"); - return -EINVAL; - } - - if (wl1273->mode !=3D WL1273_MODE_FM_RX && - wl1273->mode !=3D WL1273_MODE_FM_TX) { - pr_err("Unexpected mode: %d.\n", wl1273->mode); - return -EINVAL; - } - - r =3D snd_wl1273_fm_set_i2s_mode(core, rate, width); - if (r) - return r; - - wl1273->channels =3D params_channels(params); - r =3D snd_wl1273_fm_set_channel_number(core, wl1273->channels); - if (r) - return r; - - return 0; -} - -static const struct snd_soc_dai_ops wl1273_dai_ops =3D { - .startup =3D wl1273_startup, - .hw_params =3D wl1273_hw_params, -}; - -static struct snd_soc_dai_driver wl1273_dai =3D { - .name =3D "wl1273-fm", - .playback =3D { - .stream_name =3D "Playback", - .channels_min =3D 1, - .channels_max =3D 2, - .rates =3D SNDRV_PCM_RATE_8000_48000, - .formats =3D SNDRV_PCM_FMTBIT_S16_LE}, - .capture =3D { - .stream_name =3D "Capture", - .channels_min =3D 1, - .channels_max =3D 2, - .rates =3D SNDRV_PCM_RATE_8000_48000, - .formats =3D SNDRV_PCM_FMTBIT_S16_LE}, - .ops =3D &wl1273_dai_ops, -}; - -/* Audio interface format for the soc_card driver */ -int wl1273_get_format(struct snd_soc_component *component, unsigned int *f= mt) -{ - struct wl1273_priv *wl1273; - - if (component =3D=3D NULL || fmt =3D=3D NULL) - return -EINVAL; - - wl1273 =3D snd_soc_component_get_drvdata(component); - - switch (wl1273->mode) { - case WL1273_MODE_FM_RX: - case WL1273_MODE_FM_TX: - *fmt =3D SND_SOC_DAIFMT_I2S | - SND_SOC_DAIFMT_NB_NF | - SND_SOC_DAIFMT_CBP_CFP; - - break; - case WL1273_MODE_BT: - *fmt =3D SND_SOC_DAIFMT_DSP_A | - SND_SOC_DAIFMT_IB_NF | - SND_SOC_DAIFMT_CBP_CFP; - - break; - default: - return -EINVAL; - } - - return 0; -} -EXPORT_SYMBOL_GPL(wl1273_get_format); - -static int wl1273_probe(struct snd_soc_component *component) -{ - struct wl1273_core **core =3D component->dev->platform_data; - struct wl1273_priv *wl1273; - - dev_dbg(component->dev, "%s.\n", __func__); - - if (!core) { - dev_err(component->dev, "Platform data is missing.\n"); - return -EINVAL; - } - - wl1273 =3D kzalloc(sizeof(struct wl1273_priv), GFP_KERNEL); - if (!wl1273) - return -ENOMEM; - - wl1273->mode =3D WL1273_MODE_BT; - wl1273->core =3D *core; - - snd_soc_component_set_drvdata(component, wl1273); - - return 0; -} - -static void wl1273_remove(struct snd_soc_component *component) -{ - struct wl1273_priv *wl1273 =3D snd_soc_component_get_drvdata(component); - - dev_dbg(component->dev, "%s\n", __func__); - kfree(wl1273); -} - -static const struct snd_soc_component_driver soc_component_dev_wl1273 =3D { - .probe =3D wl1273_probe, - .remove =3D wl1273_remove, - .controls =3D wl1273_controls, - .num_controls =3D ARRAY_SIZE(wl1273_controls), - .dapm_widgets =3D wl1273_dapm_widgets, - .num_dapm_widgets =3D ARRAY_SIZE(wl1273_dapm_widgets), - .dapm_routes =3D wl1273_dapm_routes, - .num_dapm_routes =3D ARRAY_SIZE(wl1273_dapm_routes), - .idle_bias_on =3D 1, - .use_pmdown_time =3D 1, - .endianness =3D 1, -}; - -static int wl1273_platform_probe(struct platform_device *pdev) -{ - return devm_snd_soc_register_component(&pdev->dev, - &soc_component_dev_wl1273, - &wl1273_dai, 1); -} - -MODULE_ALIAS("platform:wl1273-codec"); - -static struct platform_driver wl1273_platform_driver =3D { - .driver =3D { - .name =3D "wl1273-codec", - }, - .probe =3D wl1273_platform_probe, -}; - -module_platform_driver(wl1273_platform_driver); - -MODULE_AUTHOR("Matti Aaltonen "); -MODULE_DESCRIPTION("ASoC WL1273 codec driver"); -MODULE_LICENSE("GPL"); diff --git a/sound/soc/codecs/wl1273.h b/sound/soc/codecs/wl1273.h deleted file mode 100644 index 66c312fa7eee..000000000000 --- a/sound/soc/codecs/wl1273.h +++ /dev/null @@ -1,16 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * sound/soc/codec/wl1273.h - * - * ALSA SoC WL1273 codec driver - * - * Copyright (C) Nokia Corporation - * Author: Matti Aaltonen - */ - -#ifndef __WL1273_CODEC_H__ -#define __WL1273_CODEC_H__ - -int wl1273_get_format(struct snd_soc_component *component, unsigned int *f= mt); - -#endif /* End of __WL1273_CODEC_H__ */ --=20 2.49.0 From nobody Mon Dec 15 21:27:08 2025 Received: from mx.treblig.org (mx.treblig.org [46.235.229.95]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id DBC722641F9; Wed, 25 Jun 2025 13:33:48 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=46.235.229.95 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750858430; cv=none; b=A4fI3utZn6m9C/N0q/JBAmpKQtKGYXXd2T/MaksWGe/XtfQn6G0IrAXvWaNBHVI8DYt5kaj158ddqZvWuGWkD0uTCeFyfnzl7LkDqFpDmR6iIT5H7A4Bz9Cqnn0R6R02iMGnZzpMy3sPJRUb415NYguIajZAc19JkDAUN9rESI8= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750858430; c=relaxed/simple; bh=9PM94jbIaN23LqSCDU+9vxJcEhBVzdh32bUit0iUUic=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=QiA7mgyG54r4/MCIXxyNtL6oDcwlA+GhqlAGfZSSEeM0HWjO6FBNcbvByw4sxNSWIvt0ulduRI/5uOCu3nkF8guJ+G5zwYUxaFQWZNlY0dk2wHfbd1WMjIeI+XC4sVjGZ7SKJs3NPoPO0qkPckRaBJ8pa1T/nQH798Ku5fxyyAQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=treblig.org; spf=pass smtp.mailfrom=treblig.org; dkim=pass (2048-bit key) header.d=treblig.org header.i=@treblig.org header.b=gzJOXPMe; arc=none smtp.client-ip=46.235.229.95 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=treblig.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=treblig.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=treblig.org header.i=@treblig.org header.b="gzJOXPMe" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=treblig.org ; s=bytemarkmx; h=MIME-Version:Message-ID:Date:Subject:From:Content-Type:From :Subject; bh=x8IENQRgzPZWrL9KNIvqXNVUQa9JiB/LtQpuLaDdKOw=; b=gzJOXPMe8rKPo6Br Ku+D1531A9zlyAr/uaglD1KsrIAgk+2svQZbk2QjbIKfD30ZkxCOxc3BvVJjaL6tJUKmYaQOyqIuM ey+Wul8HIxtKxTP4Baf4YQ0VslrzX8WNCPRYb+n22xBKvEvx4imG/XLvwGurX4VOBjd4JWEI9teCE 9mshg+zpvaF8vIgV+ZNlG+cjrMEK9qOf4+I4nfHTvq4yoQdLFCfyDC5v5nHWn3eBfv4dlaqNl7DCX 7r0UnIECedfIJ8Xrgay3N/jQqJ+nrZWEKq3kV7v7UAkHTbVKm7e3BegbtgQbahfaTWiwj8owhY/rf 8CFqIyfTXUPke8Pqow==; Received: from localhost ([127.0.0.1] helo=dalek.home.treblig.org) by mx.treblig.org with esmtp (Exim 4.96) (envelope-from ) id 1uUQFx-00Bvly-2N; Wed, 25 Jun 2025 13:33:41 +0000 From: linux@treblig.org To: arnd@arndb.de, lee@kernel.org, mchehab@kernel.org, lgirdwood@gmail.com, broonie@kernel.org, perex@perex.cz, tiwai@suse.com Cc: linux-media@vger.kernel.org, linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org, "Dr. David Alan Gilbert" Subject: [PATCH 3/4] mfd: wl1273-core: Remove Date: Wed, 25 Jun 2025 14:32:57 +0100 Message-ID: <20250625133258.78133-4-linux@treblig.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250625133258.78133-1-linux@treblig.org> References: <20250625133258.78133-1-linux@treblig.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: "Dr. David Alan Gilbert" The wl1273 FM radio is on Arnd's unused driver list: https://lore.kernel.org/lkml/a15bb180-401d-49ad-a212-0c81d613fbc8@app.fas= tmail.com/ remove the core. Signed-off-by: Dr. David Alan Gilbert Acked-by: Arnd Bergmann --- drivers/mfd/Kconfig | 10 -- drivers/mfd/Makefile | 1 - drivers/mfd/wl1273-core.c | 262 -------------------------------------- 3 files changed, 273 deletions(-) delete mode 100644 drivers/mfd/wl1273-core.c diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig index 6fb3768e3d71..c635790afa75 100644 --- a/drivers/mfd/Kconfig +++ b/drivers/mfd/Kconfig @@ -1889,16 +1889,6 @@ config MENELAUS and other features that are often used in portable devices like cell phones and PDAs. =20 -config MFD_WL1273_CORE - tristate "TI WL1273 FM radio" - depends on I2C - select MFD_CORE - default n - help - This is the core driver for the TI WL1273 FM radio. This MFD - driver connects the radio-wl1273 V4L2 module and the wl1273 - audio codec. - config MFD_LM3533 tristate "TI/National Semiconductor LM3533 Lighting Power chip" depends on I2C diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile index 79495f9f3457..ca351cb0ddcc 100644 --- a/drivers/mfd/Makefile +++ b/drivers/mfd/Makefile @@ -200,7 +200,6 @@ obj-$(CONFIG_MFD_RDC321X) +=3D rdc321x-southbridge.o obj-$(CONFIG_MFD_JANZ_CMODIO) +=3D janz-cmodio.o obj-$(CONFIG_MFD_TPS6586X) +=3D tps6586x.o obj-$(CONFIG_MFD_VX855) +=3D vx855.o -obj-$(CONFIG_MFD_WL1273_CORE) +=3D wl1273-core.o =20 si476x-core-y :=3D si476x-cmd.o si476x-prop.o si476x-i2c.o obj-$(CONFIG_MFD_SI476X_CORE) +=3D si476x-core.o diff --git a/drivers/mfd/wl1273-core.c b/drivers/mfd/wl1273-core.c deleted file mode 100644 index 2f185e93318e..000000000000 --- a/drivers/mfd/wl1273-core.c +++ /dev/null @@ -1,262 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-only -/* - * MFD driver for wl1273 FM radio and audio codec submodules. - * - * Copyright (C) 2011 Nokia Corporation - * Author: Matti Aaltonen - */ - -#include -#include -#include - -#define DRIVER_DESC "WL1273 FM Radio Core" - -static const struct i2c_device_id wl1273_driver_id_table[] =3D { - { WL1273_FM_DRIVER_NAME }, - { } -}; -MODULE_DEVICE_TABLE(i2c, wl1273_driver_id_table); - -static int wl1273_fm_read_reg(struct wl1273_core *core, u8 reg, u16 *value) -{ - struct i2c_client *client =3D core->client; - u8 b[2]; - int r; - - r =3D i2c_smbus_read_i2c_block_data(client, reg, sizeof(b), b); - if (r !=3D 2) { - dev_err(&client->dev, "%s: Read: %d fails.\n", __func__, reg); - return -EREMOTEIO; - } - - *value =3D (u16)b[0] << 8 | b[1]; - - return 0; -} - -static int wl1273_fm_write_cmd(struct wl1273_core *core, u8 cmd, u16 param) -{ - struct i2c_client *client =3D core->client; - u8 buf[] =3D { (param >> 8) & 0xff, param & 0xff }; - int r; - - r =3D i2c_smbus_write_i2c_block_data(client, cmd, sizeof(buf), buf); - if (r) { - dev_err(&client->dev, "%s: Cmd: %d fails.\n", __func__, cmd); - return r; - } - - return 0; -} - -static int wl1273_fm_write_data(struct wl1273_core *core, u8 *data, u16 le= n) -{ - struct i2c_client *client =3D core->client; - struct i2c_msg msg; - int r; - - msg.addr =3D client->addr; - msg.flags =3D 0; - msg.buf =3D data; - msg.len =3D len; - - r =3D i2c_transfer(client->adapter, &msg, 1); - if (r !=3D 1) { - dev_err(&client->dev, "%s: write error.\n", __func__); - return -EREMOTEIO; - } - - return 0; -} - -/** - * wl1273_fm_set_audio() - Set audio mode. - * @core: A pointer to the device struct. - * @new_mode: The new audio mode. - * - * Audio modes are WL1273_AUDIO_DIGITAL and WL1273_AUDIO_ANALOG. - */ -static int wl1273_fm_set_audio(struct wl1273_core *core, unsigned int new_= mode) -{ - int r =3D 0; - - if (core->mode =3D=3D WL1273_MODE_OFF || - core->mode =3D=3D WL1273_MODE_SUSPENDED) - return -EPERM; - - if (core->mode =3D=3D WL1273_MODE_RX && new_mode =3D=3D WL1273_AUDIO_DIGI= TAL) { - r =3D wl1273_fm_write_cmd(core, WL1273_PCM_MODE_SET, - WL1273_PCM_DEF_MODE); - if (r) - goto out; - - r =3D wl1273_fm_write_cmd(core, WL1273_I2S_MODE_CONFIG_SET, - core->i2s_mode); - if (r) - goto out; - - r =3D wl1273_fm_write_cmd(core, WL1273_AUDIO_ENABLE, - WL1273_AUDIO_ENABLE_I2S); - if (r) - goto out; - - } else if (core->mode =3D=3D WL1273_MODE_RX && - new_mode =3D=3D WL1273_AUDIO_ANALOG) { - r =3D wl1273_fm_write_cmd(core, WL1273_AUDIO_ENABLE, - WL1273_AUDIO_ENABLE_ANALOG); - if (r) - goto out; - - } else if (core->mode =3D=3D WL1273_MODE_TX && - new_mode =3D=3D WL1273_AUDIO_DIGITAL) { - r =3D wl1273_fm_write_cmd(core, WL1273_I2S_MODE_CONFIG_SET, - core->i2s_mode); - if (r) - goto out; - - r =3D wl1273_fm_write_cmd(core, WL1273_AUDIO_IO_SET, - WL1273_AUDIO_IO_SET_I2S); - if (r) - goto out; - - } else if (core->mode =3D=3D WL1273_MODE_TX && - new_mode =3D=3D WL1273_AUDIO_ANALOG) { - r =3D wl1273_fm_write_cmd(core, WL1273_AUDIO_IO_SET, - WL1273_AUDIO_IO_SET_ANALOG); - if (r) - goto out; - } - - core->audio_mode =3D new_mode; -out: - return r; -} - -/** - * wl1273_fm_set_volume() - Set volume. - * @core: A pointer to the device struct. - * @volume: The new volume value. - */ -static int wl1273_fm_set_volume(struct wl1273_core *core, unsigned int vol= ume) -{ - int r; - - if (volume > WL1273_MAX_VOLUME) - return -EINVAL; - - if (core->volume =3D=3D volume) - return 0; - - r =3D wl1273_fm_write_cmd(core, WL1273_VOLUME_SET, volume); - if (r) - return r; - - core->volume =3D volume; - return 0; -} - -static int wl1273_core_probe(struct i2c_client *client) -{ - struct wl1273_fm_platform_data *pdata =3D dev_get_platdata(&client->dev); - struct wl1273_core *core; - struct mfd_cell *cell; - int children =3D 0; - int r =3D 0; - - dev_dbg(&client->dev, "%s\n", __func__); - - if (!pdata) { - dev_err(&client->dev, "No platform data.\n"); - return -EINVAL; - } - - if (!(pdata->children & WL1273_RADIO_CHILD)) { - dev_err(&client->dev, "Cannot function without radio child.\n"); - return -EINVAL; - } - - core =3D devm_kzalloc(&client->dev, sizeof(*core), GFP_KERNEL); - if (!core) - return -ENOMEM; - - core->pdata =3D pdata; - core->client =3D client; - mutex_init(&core->lock); - - i2c_set_clientdata(client, core); - - dev_dbg(&client->dev, "%s: Have V4L2.\n", __func__); - - cell =3D &core->cells[children]; - cell->name =3D "wl1273_fm_radio"; - cell->platform_data =3D &core; - cell->pdata_size =3D sizeof(core); - children++; - - core->read =3D wl1273_fm_read_reg; - core->write =3D wl1273_fm_write_cmd; - core->write_data =3D wl1273_fm_write_data; - core->set_audio =3D wl1273_fm_set_audio; - core->set_volume =3D wl1273_fm_set_volume; - - if (pdata->children & WL1273_CODEC_CHILD) { - cell =3D &core->cells[children]; - - dev_dbg(&client->dev, "%s: Have codec.\n", __func__); - cell->name =3D "wl1273-codec"; - cell->platform_data =3D &core; - cell->pdata_size =3D sizeof(core); - children++; - } - - dev_dbg(&client->dev, "%s: number of children: %d.\n", - __func__, children); - - r =3D devm_mfd_add_devices(&client->dev, -1, core->cells, - children, NULL, 0, NULL); - if (r) - goto err; - - return 0; - -err: - pdata->free_resources(); - - dev_dbg(&client->dev, "%s\n", __func__); - - return r; -} - -static struct i2c_driver wl1273_core_driver =3D { - .driver =3D { - .name =3D WL1273_FM_DRIVER_NAME, - }, - .probe =3D wl1273_core_probe, - .id_table =3D wl1273_driver_id_table, -}; - -static int __init wl1273_core_init(void) -{ - int r; - - r =3D i2c_add_driver(&wl1273_core_driver); - if (r) { - pr_err(WL1273_FM_DRIVER_NAME - ": driver registration failed\n"); - return r; - } - - return r; -} - -static void __exit wl1273_core_exit(void) -{ - i2c_del_driver(&wl1273_core_driver); -} -late_initcall(wl1273_core_init); -module_exit(wl1273_core_exit); - -MODULE_AUTHOR("Matti Aaltonen "); -MODULE_DESCRIPTION(DRIVER_DESC); -MODULE_LICENSE("GPL"); --=20 2.49.0 From nobody Mon Dec 15 21:27:08 2025 Received: from mx.treblig.org (mx.treblig.org [46.235.229.95]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 24CB4262FED; Wed, 25 Jun 2025 13:33:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=46.235.229.95 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750858441; cv=none; b=Fon/yfy4XSZEtGehfJGkb2hrfNBLsYTYyt+0bQ5B4ehBEm4GzHkDtV3oiN96AWVlUzN2w/WVpWQY1QGn+YI/tx/9YnTCAzd6raECh35Xz8JsaAw9ivlcLw1J8N3a1tpUwG/IWaii+AscTkJEl3Hfwc5hEsBZ+2prEFlU35/kFGs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1750858441; c=relaxed/simple; bh=fdUE94Aj6Ygf+wI5w/JTwDSyh/44/wu4RIvM8ZbTejk=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version; b=YqbyJJD16smNIb47nVllj6tLHKH3jEW03eyzkVRQ4eR+dZnWhPmcz9J/yS9nAMQaabzl5wGTIL318VTeSRspy+/hVmP+Goyo5T/bJlprG/xAEYj0Zp7GX8EeHoQuH82f9kZhWxwgwOvrRMoFgDAEzJMRg5tWqQ6g5BwoPLyvZFw= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=treblig.org; spf=pass smtp.mailfrom=treblig.org; dkim=pass (2048-bit key) header.d=treblig.org header.i=@treblig.org header.b=ckAOgRla; arc=none smtp.client-ip=46.235.229.95 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=none dis=none) header.from=treblig.org Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=treblig.org Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=treblig.org header.i=@treblig.org header.b="ckAOgRla" DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=treblig.org ; s=bytemarkmx; h=MIME-Version:Message-ID:Date:Subject:From:Content-Type:From :Subject; bh=j+Zl/OfD2HpnWuD+SJA6Yd9g8QDqyJtr8RJOf4icl70=; b=ckAOgRlauISsMc1s s3mEmhKHOTfrh0j1ewYzpyrEjnV0wltS3kTu43Nw7O85dujeFXobsk7i0nhrMpVXCeuprl4UmZOrY U6OlYASzo8YJ0mgmO1yToub0fF0okRz46KZDQWeGbUlJklmvYjDW1fus/+OFVwLreKSUBAEn4QeQJ QMCRQzMku7o+mo9H0KH7vGoGAurk/LWsktoC1YZB+TF4B8o2uZwIDXiy02/7SiF0BM0+vIimaVe1R n1lZbKywmFZ6h7dM/h4pRrjtxHZuBHLtSq43HITfu0YqThqBRhxRs6hS8IUB/5d0I62gSWYiF3gy9 cPwdazLwZoT7Ph/u/A==; Received: from localhost ([127.0.0.1] helo=dalek.home.treblig.org) by mx.treblig.org with esmtp (Exim 4.96) (envelope-from ) id 1uUQG8-00Bvly-2R; Wed, 25 Jun 2025 13:33:52 +0000 From: linux@treblig.org To: arnd@arndb.de, lee@kernel.org, mchehab@kernel.org, lgirdwood@gmail.com, broonie@kernel.org, perex@perex.cz, tiwai@suse.com Cc: linux-media@vger.kernel.org, linux-sound@vger.kernel.org, linux-kernel@vger.kernel.org, "Dr. David Alan Gilbert" Subject: [PATCH 4/4] mfd: wl1273-core: Remove the header Date: Wed, 25 Jun 2025 14:32:58 +0100 Message-ID: <20250625133258.78133-5-linux@treblig.org> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250625133258.78133-1-linux@treblig.org> References: <20250625133258.78133-1-linux@treblig.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" From: "Dr. David Alan Gilbert" The wl1273 FM radio is on Arnd's unused driver list: https://lore.kernel.org/lkml/a15bb180-401d-49ad-a212-0c81d613fbc8@app.fas= tmail.com/ Other patches have removed the core, the ASoC code and the Radio code. With all those in, remove the header. Also, tidy the ref in the docs. Signed-off-by: Dr. David Alan Gilbert Acked-by: Arnd Bergmann --- .../admin-guide/media/radio-cardlist.rst | 1 - include/linux/mfd/wl1273-core.h | 277 ------------------ 2 files changed, 278 deletions(-) delete mode 100644 include/linux/mfd/wl1273-core.h diff --git a/Documentation/admin-guide/media/radio-cardlist.rst b/Documenta= tion/admin-guide/media/radio-cardlist.rst index a82a146bf912..cec724256812 100644 --- a/Documentation/admin-guide/media/radio-cardlist.rst +++ b/Documentation/admin-guide/media/radio-cardlist.rst @@ -30,7 +30,6 @@ radio-terratec TerraTec ActiveRadio ISA Standalone radio-timb Enable the Timberdale radio driver radio-trust Trust FM radio card radio-typhoon Typhoon Radio (a.k.a. EcoRadio) -radio-wl1273 Texas Instruments WL1273 I2C FM Radio fm_drv ISA radio devices fm_drv ISA radio devices radio-zoltrix Zoltrix Radio diff --git a/include/linux/mfd/wl1273-core.h b/include/linux/mfd/wl1273-cor= e.h deleted file mode 100644 index c28cf76d5c31..000000000000 --- a/include/linux/mfd/wl1273-core.h +++ /dev/null @@ -1,277 +0,0 @@ -/* SPDX-License-Identifier: GPL-2.0-only */ -/* - * include/linux/mfd/wl1273-core.h - * - * Some definitions for the wl1273 radio receiver/transmitter chip. - * - * Copyright (C) 2010 Nokia Corporation - * Author: Matti J. Aaltonen - */ - -#ifndef WL1273_CORE_H -#define WL1273_CORE_H - -#include -#include - -#define WL1273_FM_DRIVER_NAME "wl1273-fm" -#define RX71_FM_I2C_ADDR 0x22 - -#define WL1273_STEREO_GET 0 -#define WL1273_RSSI_LVL_GET 1 -#define WL1273_IF_COUNT_GET 2 -#define WL1273_FLAG_GET 3 -#define WL1273_RDS_SYNC_GET 4 -#define WL1273_RDS_DATA_GET 5 -#define WL1273_FREQ_SET 10 -#define WL1273_AF_FREQ_SET 11 -#define WL1273_MOST_MODE_SET 12 -#define WL1273_MOST_BLEND_SET 13 -#define WL1273_DEMPH_MODE_SET 14 -#define WL1273_SEARCH_LVL_SET 15 -#define WL1273_BAND_SET 16 -#define WL1273_MUTE_STATUS_SET 17 -#define WL1273_RDS_PAUSE_LVL_SET 18 -#define WL1273_RDS_PAUSE_DUR_SET 19 -#define WL1273_RDS_MEM_SET 20 -#define WL1273_RDS_BLK_B_SET 21 -#define WL1273_RDS_MSK_B_SET 22 -#define WL1273_RDS_PI_MASK_SET 23 -#define WL1273_RDS_PI_SET 24 -#define WL1273_RDS_SYSTEM_SET 25 -#define WL1273_INT_MASK_SET 26 -#define WL1273_SEARCH_DIR_SET 27 -#define WL1273_VOLUME_SET 28 -#define WL1273_AUDIO_ENABLE 29 -#define WL1273_PCM_MODE_SET 30 -#define WL1273_I2S_MODE_CONFIG_SET 31 -#define WL1273_POWER_SET 32 -#define WL1273_INTX_CONFIG_SET 33 -#define WL1273_PULL_EN_SET 34 -#define WL1273_HILO_SET 35 -#define WL1273_SWITCH2FREF 36 -#define WL1273_FREQ_DRIFT_REPORT 37 - -#define WL1273_PCE_GET 40 -#define WL1273_FIRM_VER_GET 41 -#define WL1273_ASIC_VER_GET 42 -#define WL1273_ASIC_ID_GET 43 -#define WL1273_MAN_ID_GET 44 -#define WL1273_TUNER_MODE_SET 45 -#define WL1273_STOP_SEARCH 46 -#define WL1273_RDS_CNTRL_SET 47 - -#define WL1273_WRITE_HARDWARE_REG 100 -#define WL1273_CODE_DOWNLOAD 101 -#define WL1273_RESET 102 - -#define WL1273_FM_POWER_MODE 254 -#define WL1273_FM_INTERRUPT 255 - -/* Transmitter API */ - -#define WL1273_CHANL_SET 55 -#define WL1273_SCAN_SPACING_SET 56 -#define WL1273_REF_SET 57 -#define WL1273_POWER_ENB_SET 90 -#define WL1273_POWER_ATT_SET 58 -#define WL1273_POWER_LEV_SET 59 -#define WL1273_AUDIO_DEV_SET 60 -#define WL1273_PILOT_DEV_SET 61 -#define WL1273_RDS_DEV_SET 62 -#define WL1273_PUPD_SET 91 -#define WL1273_AUDIO_IO_SET 63 -#define WL1273_PREMPH_SET 64 -#define WL1273_MONO_SET 66 -#define WL1273_MUTE 92 -#define WL1273_MPX_LMT_ENABLE 67 -#define WL1273_PI_SET 93 -#define WL1273_ECC_SET 69 -#define WL1273_PTY 70 -#define WL1273_AF 71 -#define WL1273_DISPLAY_MODE 74 -#define WL1273_RDS_REP_SET 77 -#define WL1273_RDS_CONFIG_DATA_SET 98 -#define WL1273_RDS_DATA_SET 99 -#define WL1273_RDS_DATA_ENB 94 -#define WL1273_TA_SET 78 -#define WL1273_TP_SET 79 -#define WL1273_DI_SET 80 -#define WL1273_MS_SET 81 -#define WL1273_PS_SCROLL_SPEED 82 -#define WL1273_TX_AUDIO_LEVEL_TEST 96 -#define WL1273_TX_AUDIO_LEVEL_TEST_THRESHOLD 73 -#define WL1273_TX_AUDIO_INPUT_LEVEL_RANGE_SET 54 -#define WL1273_RX_ANTENNA_SELECT 87 -#define WL1273_I2C_DEV_ADDR_SET 86 -#define WL1273_REF_ERR_CALIB_PARAM_SET 88 -#define WL1273_REF_ERR_CALIB_PERIODICITY_SET 89 -#define WL1273_SOC_INT_TRIGGER 52 -#define WL1273_SOC_AUDIO_PATH_SET 83 -#define WL1273_SOC_PCMI_OVERRIDE 84 -#define WL1273_SOC_I2S_OVERRIDE 85 -#define WL1273_RSSI_BLOCK_SCAN_FREQ_SET 95 -#define WL1273_RSSI_BLOCK_SCAN_START 97 -#define WL1273_RSSI_BLOCK_SCAN_DATA_GET 5 -#define WL1273_READ_FMANT_TUNE_VALUE 104 - -#define WL1273_RDS_OFF 0 -#define WL1273_RDS_ON 1 -#define WL1273_RDS_RESET 2 - -#define WL1273_AUDIO_DIGITAL 0 -#define WL1273_AUDIO_ANALOG 1 - -#define WL1273_MODE_RX BIT(0) -#define WL1273_MODE_TX BIT(1) -#define WL1273_MODE_OFF BIT(2) -#define WL1273_MODE_SUSPENDED BIT(3) - -#define WL1273_RADIO_CHILD BIT(0) -#define WL1273_CODEC_CHILD BIT(1) - -#define WL1273_RX_MONO 1 -#define WL1273_RX_STEREO 0 -#define WL1273_TX_MONO 0 -#define WL1273_TX_STEREO 1 - -#define WL1273_MAX_VOLUME 0xffff -#define WL1273_DEFAULT_VOLUME 0x78b8 - -/* I2S protocol, left channel first, data width 16 bits */ -#define WL1273_PCM_DEF_MODE 0x00 - -/* Rx */ -#define WL1273_AUDIO_ENABLE_I2S BIT(0) -#define WL1273_AUDIO_ENABLE_ANALOG BIT(1) - -/* Tx */ -#define WL1273_AUDIO_IO_SET_ANALOG 0 -#define WL1273_AUDIO_IO_SET_I2S 1 - -#define WL1273_PUPD_SET_OFF 0x00 -#define WL1273_PUPD_SET_ON 0x01 -#define WL1273_PUPD_SET_RETENTION 0x10 - -/* I2S mode */ -#define WL1273_IS2_WIDTH_32 0x0 -#define WL1273_IS2_WIDTH_40 0x1 -#define WL1273_IS2_WIDTH_22_23 0x2 -#define WL1273_IS2_WIDTH_23_22 0x3 -#define WL1273_IS2_WIDTH_48 0x4 -#define WL1273_IS2_WIDTH_50 0x5 -#define WL1273_IS2_WIDTH_60 0x6 -#define WL1273_IS2_WIDTH_64 0x7 -#define WL1273_IS2_WIDTH_80 0x8 -#define WL1273_IS2_WIDTH_96 0x9 -#define WL1273_IS2_WIDTH_128 0xa -#define WL1273_IS2_WIDTH 0xf - -#define WL1273_IS2_FORMAT_STD (0x0 << 4) -#define WL1273_IS2_FORMAT_LEFT (0x1 << 4) -#define WL1273_IS2_FORMAT_RIGHT (0x2 << 4) -#define WL1273_IS2_FORMAT_USER (0x3 << 4) - -#define WL1273_IS2_MASTER (0x0 << 6) -#define WL1273_IS2_SLAVEW (0x1 << 6) - -#define WL1273_IS2_TRI_AFTER_SENDING (0x0 << 7) -#define WL1273_IS2_TRI_ALWAYS_ACTIVE (0x1 << 7) - -#define WL1273_IS2_SDOWS_RR (0x0 << 8) -#define WL1273_IS2_SDOWS_RF (0x1 << 8) -#define WL1273_IS2_SDOWS_FR (0x2 << 8) -#define WL1273_IS2_SDOWS_FF (0x3 << 8) - -#define WL1273_IS2_TRI_OPT (0x0 << 10) -#define WL1273_IS2_TRI_ALWAYS (0x1 << 10) - -#define WL1273_IS2_RATE_48K (0x0 << 12) -#define WL1273_IS2_RATE_44_1K (0x1 << 12) -#define WL1273_IS2_RATE_32K (0x2 << 12) -#define WL1273_IS2_RATE_22_05K (0x4 << 12) -#define WL1273_IS2_RATE_16K (0x5 << 12) -#define WL1273_IS2_RATE_12K (0x8 << 12) -#define WL1273_IS2_RATE_11_025 (0x9 << 12) -#define WL1273_IS2_RATE_8K (0xa << 12) -#define WL1273_IS2_RATE (0xf << 12) - -#define WL1273_I2S_DEF_MODE (WL1273_IS2_WIDTH_32 | \ - WL1273_IS2_FORMAT_STD | \ - WL1273_IS2_MASTER | \ - WL1273_IS2_TRI_AFTER_SENDING | \ - WL1273_IS2_SDOWS_RR | \ - WL1273_IS2_TRI_OPT | \ - WL1273_IS2_RATE_48K) - -#define SCHAR_MIN (-128) -#define SCHAR_MAX 127 - -#define WL1273_FR_EVENT BIT(0) -#define WL1273_BL_EVENT BIT(1) -#define WL1273_RDS_EVENT BIT(2) -#define WL1273_BBLK_EVENT BIT(3) -#define WL1273_LSYNC_EVENT BIT(4) -#define WL1273_LEV_EVENT BIT(5) -#define WL1273_IFFR_EVENT BIT(6) -#define WL1273_PI_EVENT BIT(7) -#define WL1273_PD_EVENT BIT(8) -#define WL1273_STIC_EVENT BIT(9) -#define WL1273_MAL_EVENT BIT(10) -#define WL1273_POW_ENB_EVENT BIT(11) -#define WL1273_SCAN_OVER_EVENT BIT(12) -#define WL1273_ERROR_EVENT BIT(13) - -#define TUNER_MODE_STOP_SEARCH 0 -#define TUNER_MODE_PRESET 1 -#define TUNER_MODE_AUTO_SEEK 2 -#define TUNER_MODE_AF 3 -#define TUNER_MODE_AUTO_SEEK_PI 4 -#define TUNER_MODE_AUTO_SEEK_BULK 5 - -#define RDS_BLOCK_SIZE 3 - -struct wl1273_fm_platform_data { - int (*request_resources) (struct i2c_client *client); - void (*free_resources) (void); - void (*enable) (void); - void (*disable) (void); - - u8 forbidden_modes; - unsigned int children; -}; - -#define WL1273_FM_CORE_CELLS 2 - -#define WL1273_BAND_OTHER 0 -#define WL1273_BAND_JAPAN 1 - -#define WL1273_BAND_JAPAN_LOW 76000 -#define WL1273_BAND_JAPAN_HIGH 90000 -#define WL1273_BAND_OTHER_LOW 87500 -#define WL1273_BAND_OTHER_HIGH 108000 - -#define WL1273_BAND_TX_LOW 76000 -#define WL1273_BAND_TX_HIGH 108000 - -struct wl1273_core { - struct mfd_cell cells[WL1273_FM_CORE_CELLS]; - struct wl1273_fm_platform_data *pdata; - - unsigned int mode; - unsigned int i2s_mode; - unsigned int volume; - unsigned int audio_mode; - unsigned int channel_number; - struct mutex lock; /* for serializing fm radio operations */ - - struct i2c_client *client; - - int (*read)(struct wl1273_core *core, u8, u16 *); - int (*write)(struct wl1273_core *core, u8, u16); - int (*write_data)(struct wl1273_core *core, u8 *, u16); - int (*set_audio)(struct wl1273_core *core, unsigned int); - int (*set_volume)(struct wl1273_core *core, unsigned int); -}; - -#endif /* ifndef WL1273_CORE_H */ --=20 2.49.0 From nobody Mon Dec 15 21:27:08 2025 Received: from relay.hostedemail.com (smtprelay0013.hostedemail.com [216.40.44.13]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 24F601DED53 for ; Sun, 10 Aug 2025 05:10:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=216.40.44.13 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754802647; cv=none; b=aSUqdvmaczOvef8t+apH9WOh4qh7shfGDY53xYNSUgPaw39rOelcdV5DYpCaSYvjg8zEk733HdINx92h3ICFU+OLghPU62NzZsz7uzu+W7JnhCD0U8if6nPodZpAdv/wyXtQpcBHrzonEEIewEJmVQnyfiTNTkncZWSHggax8eY= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1754802647; c=relaxed/simple; bh=9FSnWZN21YBaLFde2pnRBLG+oERfvF97uAXbcUTYclc=; h=Message-ID:Subject:From:To:Cc:Date:In-Reply-To:References: Content-Type:MIME-Version; b=FNgCAzYk2ryFeWOu0I4SlronxsYgDzsnfNdWQd9c2HccIrAaswG5vEtBH685t/wfZc+dn/rp95QRXaHJfrwjj5FM4xZu7EOYspt/JrkXRzi+2B1V40lYWKg8bZOtc+D5GcXPBaVXZsMbAg5Knzb2ocak3zFJyy+Vdd733JHlFzY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=perches.com; spf=pass smtp.mailfrom=perches.com; arc=none smtp.client-ip=216.40.44.13 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=perches.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=perches.com Received: from omf19.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay04.hostedemail.com (Postfix) with ESMTP id ED52E1A020F; Sun, 10 Aug 2025 04:31:12 +0000 (UTC) Received: from [HIDDEN] (Authenticated sender: joe@perches.com) by omf19.hostedemail.com (Postfix) with ESMTPA id 1447D20026; Sun, 10 Aug 2025 04:31:10 +0000 (UTC) Message-ID: <3529faaf84a5a9a96c5c0ec4183ae0ba6e97673c.camel@perches.com> Subject: [PATCH] checkpatch: Allow http links of any length in commit logs From: Joe Perches To: Andrew Morton Cc: linux-kernel@vger.kernel.org, "Dr. David Alan Gilbert" Date: Sat, 09 Aug 2025 21:31:10 -0700 In-Reply-To: <20250625133258.78133-1-linux@treblig.org> References: <20250625133258.78133-1-linux@treblig.org> Content-Transfer-Encoding: quoted-printable User-Agent: Evolution 3.54.3 (3.54.3-1.fc41) Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 X-Stat-Signature: fp5fkhrmegpkf1weaonz3fx3di3c6nfh X-Rspamd-Server: rspamout01 X-Rspamd-Queue-Id: 1447D20026 X-Session-Marker: 6A6F6540706572636865732E636F6D X-Session-ID: U2FsdGVkX1/X5t25Ga1iS4apkFpLbuQip8RajIgvE3Q= X-HE-Tag: 1754800270-74814 X-HE-Meta: U2FsdGVkX1/szqzOwoD0gQJmrivfztLfifPFk3qG99c6V9b7JDLAOA0g0ga6PjzsUpX8XWQMgftQQMeJQDaw76PTyi/W2L2PScm7ocvE1btyLj+DRzmSnPwCpMPc8IDPS67FtQXdle1WxHECIkXEArIrUZp2aZ9BARxL0wpanRdK8UwpWAGBTmuJrnU/y6e5sqPVJVORLk6OtmHo9c5Mv3KpXpA381ZK+8tPY5Ihz36MJn37rqYZbZZ564wvTt9ZQUsSrrxn6ZQDK/zfsl0Myv4EzQka47DLB2rwGFRq2J03d3pWwfGoNYXHS7dMsLun7rC07OWdnMkAdGpLeSDReMG87F9uH/sEawajwx+mA+1dzYlE/3irEvjZV3ECftZW Content-Type: text/plain; charset="utf-8" Dave Gilbert noticed that checkpatch warns about URL links over 75 chars in length in commit logs. Fix that. Signed-off-by: Joe Perches Acked-by: Arnd Bergmann --- scripts/checkpatch.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/checkpatch.pl b/scripts/checkpatch.pl index e722dd6fa8ef3..319cc5f858858 100755 --- a/scripts/checkpatch.pl +++ b/scripts/checkpatch.pl @@ -3294,7 +3294,7 @@ sub process { # file delta changes $line =3D~ /^\s*(?:[\w\.\-\+]*\/)++[\w\.\-\+]+:/ || # filename then : - $line =3D~ /^\s*(?:Fixes:|$link_tags_search|$signature_tags)/i || + $line =3D~ /^\s*(?:Fixes:|https?:|$link_tags_search|$signature_tag= s)/i || # A Fixes:, link or signature tag line $commit_log_possible_stack_dump)) { WARN("COMMIT_LOG_LONG_LINE",