| .. | .. |
|---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
|---|
| 1 | 2 | /* |
|---|
| 2 | 3 | * drivers/media/radio/radio-si476x.c -- V4L2 driver for SI476X chips |
|---|
| 3 | 4 | * |
|---|
| .. | .. |
|---|
| 5 | 6 | * Copyright (C) 2013 Andrey Smirnov |
|---|
| 6 | 7 | * |
|---|
| 7 | 8 | * Author: Andrey Smirnov <andrew.smirnov@gmail.com> |
|---|
| 8 | | - * |
|---|
| 9 | | - * This program is free software; you can redistribute it and/or modify |
|---|
| 10 | | - * it under the terms of the GNU General Public License as published by |
|---|
| 11 | | - * the Free Software Foundation; version 2 of the License. |
|---|
| 12 | | - * |
|---|
| 13 | | - * This program is distributed in the hope that it will be useful, but |
|---|
| 14 | | - * WITHOUT ANY WARRANTY; without even the implied warranty of |
|---|
| 15 | | - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|---|
| 16 | | - * General Public License for more details. |
|---|
| 17 | | - * |
|---|
| 18 | 9 | */ |
|---|
| 19 | 10 | |
|---|
| 20 | 11 | #include <linux/module.h> |
|---|
| .. | .. |
|---|
| 114 | 105 | si476x_phase_diversity_mode_to_idx(enum si476x_phase_diversity_mode mode) |
|---|
| 115 | 106 | { |
|---|
| 116 | 107 | switch (mode) { |
|---|
| 117 | | - default: /* FALLTHROUGH */ |
|---|
| 108 | + default: |
|---|
| 109 | + fallthrough; |
|---|
| 118 | 110 | case SI476X_PHDIV_DISABLED: |
|---|
| 119 | 111 | return SI476X_IDX_PHDIV_DISABLED; |
|---|
| 120 | 112 | case SI476X_PHDIV_PRIMARY_COMBINING: |
|---|
| .. | .. |
|---|
| 340 | 332 | { |
|---|
| 341 | 333 | struct si476x_radio *radio = video_drvdata(file); |
|---|
| 342 | 334 | |
|---|
| 343 | | - strlcpy(capability->driver, radio->v4l2dev.name, |
|---|
| 335 | + strscpy(capability->driver, radio->v4l2dev.name, |
|---|
| 344 | 336 | sizeof(capability->driver)); |
|---|
| 345 | | - strlcpy(capability->card, DRIVER_CARD, sizeof(capability->card)); |
|---|
| 337 | + strscpy(capability->card, DRIVER_CARD, sizeof(capability->card)); |
|---|
| 346 | 338 | snprintf(capability->bus_info, sizeof(capability->bus_info), |
|---|
| 347 | 339 | "platform:%s", radio->v4l2dev.name); |
|---|
| 348 | | - |
|---|
| 349 | | - capability->device_caps = V4L2_CAP_TUNER |
|---|
| 350 | | - | V4L2_CAP_RADIO |
|---|
| 351 | | - | V4L2_CAP_HW_FREQ_SEEK; |
|---|
| 352 | | - |
|---|
| 353 | | - si476x_core_lock(radio->core); |
|---|
| 354 | | - if (!si476x_core_is_a_secondary_tuner(radio->core)) |
|---|
| 355 | | - capability->device_caps |= V4L2_CAP_RDS_CAPTURE |
|---|
| 356 | | - | V4L2_CAP_READWRITE; |
|---|
| 357 | | - si476x_core_unlock(radio->core); |
|---|
| 358 | | - |
|---|
| 359 | | - capability->capabilities = capability->device_caps |
|---|
| 360 | | - | V4L2_CAP_DEVICE_CAPS; |
|---|
| 361 | 340 | return 0; |
|---|
| 362 | 341 | } |
|---|
| 363 | 342 | |
|---|
| .. | .. |
|---|
| 428 | 407 | si476x_core_lock(radio->core); |
|---|
| 429 | 408 | |
|---|
| 430 | 409 | if (si476x_core_is_a_secondary_tuner(radio->core)) { |
|---|
| 431 | | - strlcpy(tuner->name, "FM (secondary)", sizeof(tuner->name)); |
|---|
| 410 | + strscpy(tuner->name, "FM (secondary)", sizeof(tuner->name)); |
|---|
| 432 | 411 | tuner->rxsubchans = 0; |
|---|
| 433 | 412 | tuner->rangelow = si476x_bands[SI476X_BAND_FM].rangelow; |
|---|
| 434 | 413 | } else if (si476x_core_has_am(radio->core)) { |
|---|
| 435 | 414 | if (si476x_core_is_a_primary_tuner(radio->core)) |
|---|
| 436 | | - strlcpy(tuner->name, "AM/FM (primary)", |
|---|
| 415 | + strscpy(tuner->name, "AM/FM (primary)", |
|---|
| 437 | 416 | sizeof(tuner->name)); |
|---|
| 438 | 417 | else |
|---|
| 439 | | - strlcpy(tuner->name, "AM/FM", sizeof(tuner->name)); |
|---|
| 418 | + strscpy(tuner->name, "AM/FM", sizeof(tuner->name)); |
|---|
| 440 | 419 | |
|---|
| 441 | 420 | tuner->rxsubchans = V4L2_TUNER_SUB_MONO | V4L2_TUNER_SUB_STEREO |
|---|
| 442 | 421 | | V4L2_TUNER_SUB_RDS; |
|---|
| .. | .. |
|---|
| 446 | 425 | |
|---|
| 447 | 426 | tuner->rangelow = si476x_bands[SI476X_BAND_AM].rangelow; |
|---|
| 448 | 427 | } else { |
|---|
| 449 | | - strlcpy(tuner->name, "FM", sizeof(tuner->name)); |
|---|
| 428 | + strscpy(tuner->name, "FM", sizeof(tuner->name)); |
|---|
| 450 | 429 | tuner->rxsubchans = V4L2_TUNER_SUB_RDS; |
|---|
| 451 | 430 | tuner->capability |= V4L2_TUNER_CAP_RDS |
|---|
| 452 | 431 | | V4L2_TUNER_CAP_RDS_BLOCK_IO |
|---|
| .. | .. |
|---|
| 1366 | 1345 | }; |
|---|
| 1367 | 1346 | |
|---|
| 1368 | 1347 | |
|---|
| 1369 | | -static int si476x_radio_init_debugfs(struct si476x_radio *radio) |
|---|
| 1348 | +static void si476x_radio_init_debugfs(struct si476x_radio *radio) |
|---|
| 1370 | 1349 | { |
|---|
| 1371 | | - struct dentry *dentry; |
|---|
| 1372 | | - int ret; |
|---|
| 1350 | + radio->debugfs = debugfs_create_dir(dev_name(radio->v4l2dev.dev), NULL); |
|---|
| 1373 | 1351 | |
|---|
| 1374 | | - dentry = debugfs_create_dir(dev_name(radio->v4l2dev.dev), NULL); |
|---|
| 1375 | | - if (IS_ERR(dentry)) { |
|---|
| 1376 | | - ret = PTR_ERR(dentry); |
|---|
| 1377 | | - goto exit; |
|---|
| 1378 | | - } |
|---|
| 1379 | | - radio->debugfs = dentry; |
|---|
| 1352 | + debugfs_create_file("acf", S_IRUGO, radio->debugfs, radio, |
|---|
| 1353 | + &radio_acf_fops); |
|---|
| 1380 | 1354 | |
|---|
| 1381 | | - dentry = debugfs_create_file("acf", S_IRUGO, |
|---|
| 1382 | | - radio->debugfs, radio, &radio_acf_fops); |
|---|
| 1383 | | - if (IS_ERR(dentry)) { |
|---|
| 1384 | | - ret = PTR_ERR(dentry); |
|---|
| 1385 | | - goto cleanup; |
|---|
| 1386 | | - } |
|---|
| 1355 | + debugfs_create_file("rds_blckcnt", S_IRUGO, radio->debugfs, radio, |
|---|
| 1356 | + &radio_rds_blckcnt_fops); |
|---|
| 1387 | 1357 | |
|---|
| 1388 | | - dentry = debugfs_create_file("rds_blckcnt", S_IRUGO, |
|---|
| 1389 | | - radio->debugfs, radio, |
|---|
| 1390 | | - &radio_rds_blckcnt_fops); |
|---|
| 1391 | | - if (IS_ERR(dentry)) { |
|---|
| 1392 | | - ret = PTR_ERR(dentry); |
|---|
| 1393 | | - goto cleanup; |
|---|
| 1394 | | - } |
|---|
| 1358 | + debugfs_create_file("agc", S_IRUGO, radio->debugfs, radio, |
|---|
| 1359 | + &radio_agc_fops); |
|---|
| 1395 | 1360 | |
|---|
| 1396 | | - dentry = debugfs_create_file("agc", S_IRUGO, |
|---|
| 1397 | | - radio->debugfs, radio, &radio_agc_fops); |
|---|
| 1398 | | - if (IS_ERR(dentry)) { |
|---|
| 1399 | | - ret = PTR_ERR(dentry); |
|---|
| 1400 | | - goto cleanup; |
|---|
| 1401 | | - } |
|---|
| 1361 | + debugfs_create_file("rsq", S_IRUGO, radio->debugfs, radio, |
|---|
| 1362 | + &radio_rsq_fops); |
|---|
| 1402 | 1363 | |
|---|
| 1403 | | - dentry = debugfs_create_file("rsq", S_IRUGO, |
|---|
| 1404 | | - radio->debugfs, radio, &radio_rsq_fops); |
|---|
| 1405 | | - if (IS_ERR(dentry)) { |
|---|
| 1406 | | - ret = PTR_ERR(dentry); |
|---|
| 1407 | | - goto cleanup; |
|---|
| 1408 | | - } |
|---|
| 1409 | | - |
|---|
| 1410 | | - dentry = debugfs_create_file("rsq_primary", S_IRUGO, |
|---|
| 1411 | | - radio->debugfs, radio, |
|---|
| 1412 | | - &radio_rsq_primary_fops); |
|---|
| 1413 | | - if (IS_ERR(dentry)) { |
|---|
| 1414 | | - ret = PTR_ERR(dentry); |
|---|
| 1415 | | - goto cleanup; |
|---|
| 1416 | | - } |
|---|
| 1417 | | - |
|---|
| 1418 | | - return 0; |
|---|
| 1419 | | -cleanup: |
|---|
| 1420 | | - debugfs_remove_recursive(radio->debugfs); |
|---|
| 1421 | | -exit: |
|---|
| 1422 | | - return ret; |
|---|
| 1364 | + debugfs_create_file("rsq_primary", S_IRUGO, radio->debugfs, radio, |
|---|
| 1365 | + &radio_rsq_primary_fops); |
|---|
| 1423 | 1366 | } |
|---|
| 1424 | 1367 | |
|---|
| 1425 | 1368 | |
|---|
| .. | .. |
|---|
| 1468 | 1411 | |
|---|
| 1469 | 1412 | radio->videodev.v4l2_dev = &radio->v4l2dev; |
|---|
| 1470 | 1413 | radio->videodev.ioctl_ops = &si4761_ioctl_ops; |
|---|
| 1414 | + radio->videodev.device_caps = V4L2_CAP_TUNER | V4L2_CAP_RADIO | |
|---|
| 1415 | + V4L2_CAP_HW_FREQ_SEEK; |
|---|
| 1416 | + |
|---|
| 1417 | + si476x_core_lock(radio->core); |
|---|
| 1418 | + if (!si476x_core_is_a_secondary_tuner(radio->core)) |
|---|
| 1419 | + radio->videodev.device_caps |= V4L2_CAP_RDS_CAPTURE | |
|---|
| 1420 | + V4L2_CAP_READWRITE; |
|---|
| 1421 | + si476x_core_unlock(radio->core); |
|---|
| 1471 | 1422 | |
|---|
| 1472 | 1423 | video_set_drvdata(&radio->videodev, radio); |
|---|
| 1473 | 1424 | platform_set_drvdata(pdev, radio); |
|---|
| .. | .. |
|---|
| 1548 | 1499 | goto exit; |
|---|
| 1549 | 1500 | } |
|---|
| 1550 | 1501 | |
|---|
| 1551 | | - rval = si476x_radio_init_debugfs(radio); |
|---|
| 1552 | | - if (rval < 0) { |
|---|
| 1553 | | - dev_err(&pdev->dev, "Could not creat debugfs interface\n"); |
|---|
| 1554 | | - goto exit; |
|---|
| 1555 | | - } |
|---|
| 1502 | + si476x_radio_init_debugfs(radio); |
|---|
| 1556 | 1503 | |
|---|
| 1557 | 1504 | return 0; |
|---|
| 1558 | 1505 | exit: |
|---|