aw2-alsa.c (18375B)
1// SPDX-License-Identifier: GPL-2.0-only 2/***************************************************************************** 3 * 4 * Copyright (C) 2008 Cedric Bregardis <cedric.bregardis@free.fr> and 5 * Jean-Christian Hassler <jhassler@free.fr> 6 * 7 * This file is part of the Audiowerk2 ALSA driver 8 * 9 *****************************************************************************/ 10#include <linux/init.h> 11#include <linux/pci.h> 12#include <linux/dma-mapping.h> 13#include <linux/slab.h> 14#include <linux/interrupt.h> 15#include <linux/delay.h> 16#include <linux/io.h> 17#include <linux/module.h> 18#include <sound/core.h> 19#include <sound/initval.h> 20#include <sound/pcm.h> 21#include <sound/pcm_params.h> 22#include <sound/control.h> 23 24#include "saa7146.h" 25#include "aw2-saa7146.h" 26 27MODULE_AUTHOR("Cedric Bregardis <cedric.bregardis@free.fr>, " 28 "Jean-Christian Hassler <jhassler@free.fr>"); 29MODULE_DESCRIPTION("Emagic Audiowerk 2 sound driver"); 30MODULE_LICENSE("GPL"); 31 32/********************************* 33 * DEFINES 34 ********************************/ 35#define CTL_ROUTE_ANALOG 0 36#define CTL_ROUTE_DIGITAL 1 37 38/********************************* 39 * TYPEDEFS 40 ********************************/ 41 /* hardware definition */ 42static const struct snd_pcm_hardware snd_aw2_playback_hw = { 43 .info = (SNDRV_PCM_INFO_MMAP | 44 SNDRV_PCM_INFO_INTERLEAVED | 45 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID), 46 .formats = SNDRV_PCM_FMTBIT_S16_LE, 47 .rates = SNDRV_PCM_RATE_44100, 48 .rate_min = 44100, 49 .rate_max = 44100, 50 .channels_min = 2, 51 .channels_max = 4, 52 .buffer_bytes_max = 32768, 53 .period_bytes_min = 4096, 54 .period_bytes_max = 32768, 55 .periods_min = 1, 56 .periods_max = 1024, 57}; 58 59static const struct snd_pcm_hardware snd_aw2_capture_hw = { 60 .info = (SNDRV_PCM_INFO_MMAP | 61 SNDRV_PCM_INFO_INTERLEAVED | 62 SNDRV_PCM_INFO_BLOCK_TRANSFER | SNDRV_PCM_INFO_MMAP_VALID), 63 .formats = SNDRV_PCM_FMTBIT_S16_LE, 64 .rates = SNDRV_PCM_RATE_44100, 65 .rate_min = 44100, 66 .rate_max = 44100, 67 .channels_min = 2, 68 .channels_max = 2, 69 .buffer_bytes_max = 32768, 70 .period_bytes_min = 4096, 71 .period_bytes_max = 32768, 72 .periods_min = 1, 73 .periods_max = 1024, 74}; 75 76struct aw2_pcm_device { 77 struct snd_pcm *pcm; 78 unsigned int stream_number; 79 struct aw2 *chip; 80}; 81 82struct aw2 { 83 struct snd_aw2_saa7146 saa7146; 84 85 struct pci_dev *pci; 86 int irq; 87 spinlock_t reg_lock; 88 struct mutex mtx; 89 90 unsigned long iobase_phys; 91 void __iomem *iobase_virt; 92 93 struct snd_card *card; 94 95 struct aw2_pcm_device device_playback[NB_STREAM_PLAYBACK]; 96 struct aw2_pcm_device device_capture[NB_STREAM_CAPTURE]; 97}; 98 99/********************************* 100 * FUNCTION DECLARATIONS 101 ********************************/ 102static int snd_aw2_create(struct snd_card *card, struct pci_dev *pci); 103static int snd_aw2_probe(struct pci_dev *pci, 104 const struct pci_device_id *pci_id); 105static int snd_aw2_pcm_playback_open(struct snd_pcm_substream *substream); 106static int snd_aw2_pcm_playback_close(struct snd_pcm_substream *substream); 107static int snd_aw2_pcm_capture_open(struct snd_pcm_substream *substream); 108static int snd_aw2_pcm_capture_close(struct snd_pcm_substream *substream); 109static int snd_aw2_pcm_prepare_playback(struct snd_pcm_substream *substream); 110static int snd_aw2_pcm_prepare_capture(struct snd_pcm_substream *substream); 111static int snd_aw2_pcm_trigger_playback(struct snd_pcm_substream *substream, 112 int cmd); 113static int snd_aw2_pcm_trigger_capture(struct snd_pcm_substream *substream, 114 int cmd); 115static snd_pcm_uframes_t snd_aw2_pcm_pointer_playback(struct snd_pcm_substream 116 *substream); 117static snd_pcm_uframes_t snd_aw2_pcm_pointer_capture(struct snd_pcm_substream 118 *substream); 119static int snd_aw2_new_pcm(struct aw2 *chip); 120 121static int snd_aw2_control_switch_capture_info(struct snd_kcontrol *kcontrol, 122 struct snd_ctl_elem_info *uinfo); 123static int snd_aw2_control_switch_capture_get(struct snd_kcontrol *kcontrol, 124 struct snd_ctl_elem_value 125 *ucontrol); 126static int snd_aw2_control_switch_capture_put(struct snd_kcontrol *kcontrol, 127 struct snd_ctl_elem_value 128 *ucontrol); 129 130/********************************* 131 * VARIABLES 132 ********************************/ 133static int index[SNDRV_CARDS] = SNDRV_DEFAULT_IDX; 134static char *id[SNDRV_CARDS] = SNDRV_DEFAULT_STR; 135static bool enable[SNDRV_CARDS] = SNDRV_DEFAULT_ENABLE_PNP; 136 137module_param_array(index, int, NULL, 0444); 138MODULE_PARM_DESC(index, "Index value for Audiowerk2 soundcard."); 139module_param_array(id, charp, NULL, 0444); 140MODULE_PARM_DESC(id, "ID string for the Audiowerk2 soundcard."); 141module_param_array(enable, bool, NULL, 0444); 142MODULE_PARM_DESC(enable, "Enable Audiowerk2 soundcard."); 143 144static const struct pci_device_id snd_aw2_ids[] = { 145 {PCI_VENDOR_ID_PHILIPS, PCI_DEVICE_ID_PHILIPS_SAA7146, 0, 0, 146 0, 0, 0}, 147 {0} 148}; 149 150MODULE_DEVICE_TABLE(pci, snd_aw2_ids); 151 152/* pci_driver definition */ 153static struct pci_driver aw2_driver = { 154 .name = KBUILD_MODNAME, 155 .id_table = snd_aw2_ids, 156 .probe = snd_aw2_probe, 157}; 158 159module_pci_driver(aw2_driver); 160 161/* operators for playback PCM alsa interface */ 162static const struct snd_pcm_ops snd_aw2_playback_ops = { 163 .open = snd_aw2_pcm_playback_open, 164 .close = snd_aw2_pcm_playback_close, 165 .prepare = snd_aw2_pcm_prepare_playback, 166 .trigger = snd_aw2_pcm_trigger_playback, 167 .pointer = snd_aw2_pcm_pointer_playback, 168}; 169 170/* operators for capture PCM alsa interface */ 171static const struct snd_pcm_ops snd_aw2_capture_ops = { 172 .open = snd_aw2_pcm_capture_open, 173 .close = snd_aw2_pcm_capture_close, 174 .prepare = snd_aw2_pcm_prepare_capture, 175 .trigger = snd_aw2_pcm_trigger_capture, 176 .pointer = snd_aw2_pcm_pointer_capture, 177}; 178 179static const struct snd_kcontrol_new aw2_control = { 180 .iface = SNDRV_CTL_ELEM_IFACE_MIXER, 181 .name = "PCM Capture Route", 182 .index = 0, 183 .access = SNDRV_CTL_ELEM_ACCESS_READWRITE, 184 .private_value = 0xffff, 185 .info = snd_aw2_control_switch_capture_info, 186 .get = snd_aw2_control_switch_capture_get, 187 .put = snd_aw2_control_switch_capture_put 188}; 189 190/********************************* 191 * FUNCTION IMPLEMENTATIONS 192 ********************************/ 193 194/* component-destructor */ 195static void snd_aw2_free(struct snd_card *card) 196{ 197 struct aw2 *chip = card->private_data; 198 199 /* Free hardware */ 200 snd_aw2_saa7146_free(&chip->saa7146); 201} 202 203/* chip-specific constructor */ 204static int snd_aw2_create(struct snd_card *card, 205 struct pci_dev *pci) 206{ 207 struct aw2 *chip = card->private_data; 208 int err; 209 210 /* initialize the PCI entry */ 211 err = pcim_enable_device(pci); 212 if (err < 0) 213 return err; 214 pci_set_master(pci); 215 216 /* check PCI availability (32bit DMA) */ 217 if (dma_set_mask_and_coherent(&pci->dev, DMA_BIT_MASK(32))) { 218 dev_err(card->dev, "Impossible to set 32bit mask DMA\n"); 219 return -ENXIO; 220 } 221 222 /* initialize the stuff */ 223 chip->card = card; 224 chip->pci = pci; 225 chip->irq = -1; 226 227 /* (1) PCI resource allocation */ 228 err = pcim_iomap_regions(pci, 1 << 0, "Audiowerk2"); 229 if (err < 0) 230 return err; 231 chip->iobase_phys = pci_resource_start(pci, 0); 232 chip->iobase_virt = pcim_iomap_table(pci)[0]; 233 234 /* (2) initialization of the chip hardware */ 235 snd_aw2_saa7146_setup(&chip->saa7146, chip->iobase_virt); 236 237 if (devm_request_irq(&pci->dev, pci->irq, snd_aw2_saa7146_interrupt, 238 IRQF_SHARED, KBUILD_MODNAME, chip)) { 239 dev_err(card->dev, "Cannot grab irq %d\n", pci->irq); 240 return -EBUSY; 241 } 242 chip->irq = pci->irq; 243 card->sync_irq = chip->irq; 244 card->private_free = snd_aw2_free; 245 246 dev_info(card->dev, 247 "Audiowerk 2 sound card (saa7146 chipset) detected and managed\n"); 248 return 0; 249} 250 251/* constructor */ 252static int snd_aw2_probe(struct pci_dev *pci, 253 const struct pci_device_id *pci_id) 254{ 255 static int dev; 256 struct snd_card *card; 257 struct aw2 *chip; 258 int err; 259 260 /* (1) Continue if device is not enabled, else inc dev */ 261 if (dev >= SNDRV_CARDS) 262 return -ENODEV; 263 if (!enable[dev]) { 264 dev++; 265 return -ENOENT; 266 } 267 268 /* (2) Create card instance */ 269 err = snd_devm_card_new(&pci->dev, index[dev], id[dev], THIS_MODULE, 270 sizeof(*chip), &card); 271 if (err < 0) 272 return err; 273 chip = card->private_data; 274 275 /* (3) Create main component */ 276 err = snd_aw2_create(card, pci); 277 if (err < 0) 278 goto error; 279 280 /* initialize mutex */ 281 mutex_init(&chip->mtx); 282 /* init spinlock */ 283 spin_lock_init(&chip->reg_lock); 284 /* (4) Define driver ID and name string */ 285 strcpy(card->driver, "aw2"); 286 strcpy(card->shortname, "Audiowerk2"); 287 288 sprintf(card->longname, "%s with SAA7146 irq %i", 289 card->shortname, chip->irq); 290 291 /* (5) Create other components */ 292 snd_aw2_new_pcm(chip); 293 294 /* (6) Register card instance */ 295 err = snd_card_register(card); 296 if (err < 0) 297 goto error; 298 299 /* (7) Set PCI driver data */ 300 pci_set_drvdata(pci, card); 301 302 dev++; 303 return 0; 304 305 error: 306 snd_card_free(card); 307 return err; 308} 309 310/* open callback */ 311static int snd_aw2_pcm_playback_open(struct snd_pcm_substream *substream) 312{ 313 struct snd_pcm_runtime *runtime = substream->runtime; 314 315 dev_dbg(substream->pcm->card->dev, "Playback_open\n"); 316 runtime->hw = snd_aw2_playback_hw; 317 return 0; 318} 319 320/* close callback */ 321static int snd_aw2_pcm_playback_close(struct snd_pcm_substream *substream) 322{ 323 return 0; 324 325} 326 327static int snd_aw2_pcm_capture_open(struct snd_pcm_substream *substream) 328{ 329 struct snd_pcm_runtime *runtime = substream->runtime; 330 331 dev_dbg(substream->pcm->card->dev, "Capture_open\n"); 332 runtime->hw = snd_aw2_capture_hw; 333 return 0; 334} 335 336/* close callback */ 337static int snd_aw2_pcm_capture_close(struct snd_pcm_substream *substream) 338{ 339 /* TODO: something to do ? */ 340 return 0; 341} 342 343/* prepare callback for playback */ 344static int snd_aw2_pcm_prepare_playback(struct snd_pcm_substream *substream) 345{ 346 struct aw2_pcm_device *pcm_device = snd_pcm_substream_chip(substream); 347 struct aw2 *chip = pcm_device->chip; 348 struct snd_pcm_runtime *runtime = substream->runtime; 349 unsigned long period_size, buffer_size; 350 351 mutex_lock(&chip->mtx); 352 353 period_size = snd_pcm_lib_period_bytes(substream); 354 buffer_size = snd_pcm_lib_buffer_bytes(substream); 355 356 snd_aw2_saa7146_pcm_init_playback(&chip->saa7146, 357 pcm_device->stream_number, 358 runtime->dma_addr, period_size, 359 buffer_size); 360 361 /* Define Interrupt callback */ 362 snd_aw2_saa7146_define_it_playback_callback(pcm_device->stream_number, 363 (snd_aw2_saa7146_it_cb) 364 snd_pcm_period_elapsed, 365 (void *)substream); 366 367 mutex_unlock(&chip->mtx); 368 369 return 0; 370} 371 372/* prepare callback for capture */ 373static int snd_aw2_pcm_prepare_capture(struct snd_pcm_substream *substream) 374{ 375 struct aw2_pcm_device *pcm_device = snd_pcm_substream_chip(substream); 376 struct aw2 *chip = pcm_device->chip; 377 struct snd_pcm_runtime *runtime = substream->runtime; 378 unsigned long period_size, buffer_size; 379 380 mutex_lock(&chip->mtx); 381 382 period_size = snd_pcm_lib_period_bytes(substream); 383 buffer_size = snd_pcm_lib_buffer_bytes(substream); 384 385 snd_aw2_saa7146_pcm_init_capture(&chip->saa7146, 386 pcm_device->stream_number, 387 runtime->dma_addr, period_size, 388 buffer_size); 389 390 /* Define Interrupt callback */ 391 snd_aw2_saa7146_define_it_capture_callback(pcm_device->stream_number, 392 (snd_aw2_saa7146_it_cb) 393 snd_pcm_period_elapsed, 394 (void *)substream); 395 396 mutex_unlock(&chip->mtx); 397 398 return 0; 399} 400 401/* playback trigger callback */ 402static int snd_aw2_pcm_trigger_playback(struct snd_pcm_substream *substream, 403 int cmd) 404{ 405 int status = 0; 406 struct aw2_pcm_device *pcm_device = snd_pcm_substream_chip(substream); 407 struct aw2 *chip = pcm_device->chip; 408 spin_lock(&chip->reg_lock); 409 switch (cmd) { 410 case SNDRV_PCM_TRIGGER_START: 411 snd_aw2_saa7146_pcm_trigger_start_playback(&chip->saa7146, 412 pcm_device-> 413 stream_number); 414 break; 415 case SNDRV_PCM_TRIGGER_STOP: 416 snd_aw2_saa7146_pcm_trigger_stop_playback(&chip->saa7146, 417 pcm_device-> 418 stream_number); 419 break; 420 default: 421 status = -EINVAL; 422 } 423 spin_unlock(&chip->reg_lock); 424 return status; 425} 426 427/* capture trigger callback */ 428static int snd_aw2_pcm_trigger_capture(struct snd_pcm_substream *substream, 429 int cmd) 430{ 431 int status = 0; 432 struct aw2_pcm_device *pcm_device = snd_pcm_substream_chip(substream); 433 struct aw2 *chip = pcm_device->chip; 434 spin_lock(&chip->reg_lock); 435 switch (cmd) { 436 case SNDRV_PCM_TRIGGER_START: 437 snd_aw2_saa7146_pcm_trigger_start_capture(&chip->saa7146, 438 pcm_device-> 439 stream_number); 440 break; 441 case SNDRV_PCM_TRIGGER_STOP: 442 snd_aw2_saa7146_pcm_trigger_stop_capture(&chip->saa7146, 443 pcm_device-> 444 stream_number); 445 break; 446 default: 447 status = -EINVAL; 448 } 449 spin_unlock(&chip->reg_lock); 450 return status; 451} 452 453/* playback pointer callback */ 454static snd_pcm_uframes_t snd_aw2_pcm_pointer_playback(struct snd_pcm_substream 455 *substream) 456{ 457 struct aw2_pcm_device *pcm_device = snd_pcm_substream_chip(substream); 458 struct aw2 *chip = pcm_device->chip; 459 unsigned int current_ptr; 460 461 /* get the current hardware pointer */ 462 struct snd_pcm_runtime *runtime = substream->runtime; 463 current_ptr = 464 snd_aw2_saa7146_get_hw_ptr_playback(&chip->saa7146, 465 pcm_device->stream_number, 466 runtime->dma_area, 467 runtime->buffer_size); 468 469 return bytes_to_frames(substream->runtime, current_ptr); 470} 471 472/* capture pointer callback */ 473static snd_pcm_uframes_t snd_aw2_pcm_pointer_capture(struct snd_pcm_substream 474 *substream) 475{ 476 struct aw2_pcm_device *pcm_device = snd_pcm_substream_chip(substream); 477 struct aw2 *chip = pcm_device->chip; 478 unsigned int current_ptr; 479 480 /* get the current hardware pointer */ 481 struct snd_pcm_runtime *runtime = substream->runtime; 482 current_ptr = 483 snd_aw2_saa7146_get_hw_ptr_capture(&chip->saa7146, 484 pcm_device->stream_number, 485 runtime->dma_area, 486 runtime->buffer_size); 487 488 return bytes_to_frames(substream->runtime, current_ptr); 489} 490 491/* create a pcm device */ 492static int snd_aw2_new_pcm(struct aw2 *chip) 493{ 494 struct snd_pcm *pcm_playback_ana; 495 struct snd_pcm *pcm_playback_num; 496 struct snd_pcm *pcm_capture; 497 struct aw2_pcm_device *pcm_device; 498 int err = 0; 499 500 /* Create new Alsa PCM device */ 501 502 err = snd_pcm_new(chip->card, "Audiowerk2 analog playback", 0, 1, 0, 503 &pcm_playback_ana); 504 if (err < 0) { 505 dev_err(chip->card->dev, "snd_pcm_new error (0x%X)\n", err); 506 return err; 507 } 508 509 /* Creation ok */ 510 pcm_device = &chip->device_playback[NUM_STREAM_PLAYBACK_ANA]; 511 512 /* Set PCM device name */ 513 strcpy(pcm_playback_ana->name, "Analog playback"); 514 /* Associate private data to PCM device */ 515 pcm_playback_ana->private_data = pcm_device; 516 /* set operators of PCM device */ 517 snd_pcm_set_ops(pcm_playback_ana, SNDRV_PCM_STREAM_PLAYBACK, 518 &snd_aw2_playback_ops); 519 /* store PCM device */ 520 pcm_device->pcm = pcm_playback_ana; 521 /* give base chip pointer to our internal pcm device 522 structure */ 523 pcm_device->chip = chip; 524 /* Give stream number to PCM device */ 525 pcm_device->stream_number = NUM_STREAM_PLAYBACK_ANA; 526 527 /* pre-allocation of buffers */ 528 /* Preallocate continuous pages. */ 529 snd_pcm_set_managed_buffer_all(pcm_playback_ana, 530 SNDRV_DMA_TYPE_DEV, 531 &chip->pci->dev, 532 64 * 1024, 64 * 1024); 533 534 err = snd_pcm_new(chip->card, "Audiowerk2 digital playback", 1, 1, 0, 535 &pcm_playback_num); 536 537 if (err < 0) { 538 dev_err(chip->card->dev, "snd_pcm_new error (0x%X)\n", err); 539 return err; 540 } 541 /* Creation ok */ 542 pcm_device = &chip->device_playback[NUM_STREAM_PLAYBACK_DIG]; 543 544 /* Set PCM device name */ 545 strcpy(pcm_playback_num->name, "Digital playback"); 546 /* Associate private data to PCM device */ 547 pcm_playback_num->private_data = pcm_device; 548 /* set operators of PCM device */ 549 snd_pcm_set_ops(pcm_playback_num, SNDRV_PCM_STREAM_PLAYBACK, 550 &snd_aw2_playback_ops); 551 /* store PCM device */ 552 pcm_device->pcm = pcm_playback_num; 553 /* give base chip pointer to our internal pcm device 554 structure */ 555 pcm_device->chip = chip; 556 /* Give stream number to PCM device */ 557 pcm_device->stream_number = NUM_STREAM_PLAYBACK_DIG; 558 559 /* pre-allocation of buffers */ 560 /* Preallocate continuous pages. */ 561 snd_pcm_set_managed_buffer_all(pcm_playback_num, 562 SNDRV_DMA_TYPE_DEV, 563 &chip->pci->dev, 564 64 * 1024, 64 * 1024); 565 566 err = snd_pcm_new(chip->card, "Audiowerk2 capture", 2, 0, 1, 567 &pcm_capture); 568 569 if (err < 0) { 570 dev_err(chip->card->dev, "snd_pcm_new error (0x%X)\n", err); 571 return err; 572 } 573 574 /* Creation ok */ 575 pcm_device = &chip->device_capture[NUM_STREAM_CAPTURE_ANA]; 576 577 /* Set PCM device name */ 578 strcpy(pcm_capture->name, "Capture"); 579 /* Associate private data to PCM device */ 580 pcm_capture->private_data = pcm_device; 581 /* set operators of PCM device */ 582 snd_pcm_set_ops(pcm_capture, SNDRV_PCM_STREAM_CAPTURE, 583 &snd_aw2_capture_ops); 584 /* store PCM device */ 585 pcm_device->pcm = pcm_capture; 586 /* give base chip pointer to our internal pcm device 587 structure */ 588 pcm_device->chip = chip; 589 /* Give stream number to PCM device */ 590 pcm_device->stream_number = NUM_STREAM_CAPTURE_ANA; 591 592 /* pre-allocation of buffers */ 593 /* Preallocate continuous pages. */ 594 snd_pcm_set_managed_buffer_all(pcm_capture, 595 SNDRV_DMA_TYPE_DEV, 596 &chip->pci->dev, 597 64 * 1024, 64 * 1024); 598 599 /* Create control */ 600 err = snd_ctl_add(chip->card, snd_ctl_new1(&aw2_control, chip)); 601 if (err < 0) { 602 dev_err(chip->card->dev, "snd_ctl_add error (0x%X)\n", err); 603 return err; 604 } 605 606 return 0; 607} 608 609static int snd_aw2_control_switch_capture_info(struct snd_kcontrol *kcontrol, 610 struct snd_ctl_elem_info *uinfo) 611{ 612 static const char * const texts[2] = { 613 "Analog", "Digital" 614 }; 615 return snd_ctl_enum_info(uinfo, 1, 2, texts); 616} 617 618static int snd_aw2_control_switch_capture_get(struct snd_kcontrol *kcontrol, 619 struct snd_ctl_elem_value 620 *ucontrol) 621{ 622 struct aw2 *chip = snd_kcontrol_chip(kcontrol); 623 if (snd_aw2_saa7146_is_using_digital_input(&chip->saa7146)) 624 ucontrol->value.enumerated.item[0] = CTL_ROUTE_DIGITAL; 625 else 626 ucontrol->value.enumerated.item[0] = CTL_ROUTE_ANALOG; 627 return 0; 628} 629 630static int snd_aw2_control_switch_capture_put(struct snd_kcontrol *kcontrol, 631 struct snd_ctl_elem_value 632 *ucontrol) 633{ 634 struct aw2 *chip = snd_kcontrol_chip(kcontrol); 635 int changed = 0; 636 int is_disgital = 637 snd_aw2_saa7146_is_using_digital_input(&chip->saa7146); 638 639 if (((ucontrol->value.integer.value[0] == CTL_ROUTE_DIGITAL) 640 && !is_disgital) 641 || ((ucontrol->value.integer.value[0] == CTL_ROUTE_ANALOG) 642 && is_disgital)) { 643 snd_aw2_saa7146_use_digital_input(&chip->saa7146, !is_disgital); 644 changed = 1; 645 } 646 return changed; 647}