18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */ 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * PC-Speaker driver for Linux 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * Copyright (C) 1993-1997 Michael Beck 68c2ecf20Sopenharmony_ci * Copyright (C) 1997-2001 David Woodhouse 78c2ecf20Sopenharmony_ci * Copyright (C) 2001-2008 Stas Sergeev 88c2ecf20Sopenharmony_ci */ 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#ifndef __PCSP_H__ 118c2ecf20Sopenharmony_ci#define __PCSP_H__ 128c2ecf20Sopenharmony_ci 138c2ecf20Sopenharmony_ci#include <linux/hrtimer.h> 148c2ecf20Sopenharmony_ci#include <linux/i8253.h> 158c2ecf20Sopenharmony_ci#include <linux/timex.h> 168c2ecf20Sopenharmony_ci 178c2ecf20Sopenharmony_ci#define PCSP_SOUND_VERSION 0x400 /* read 4.00 */ 188c2ecf20Sopenharmony_ci#define PCSP_DEBUG 0 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci/* default timer freq for PC-Speaker: 18643 Hz */ 218c2ecf20Sopenharmony_ci#define DIV_18KHZ 64 228c2ecf20Sopenharmony_ci#define MAX_DIV DIV_18KHZ 238c2ecf20Sopenharmony_ci#define CALC_DIV(d) (MAX_DIV >> (d)) 248c2ecf20Sopenharmony_ci#define CUR_DIV() CALC_DIV(chip->treble) 258c2ecf20Sopenharmony_ci#define PCSP_MAX_TREBLE 1 268c2ecf20Sopenharmony_ci 278c2ecf20Sopenharmony_ci/* unfortunately, with hrtimers 37KHz does not work very well :( */ 288c2ecf20Sopenharmony_ci#define PCSP_DEFAULT_TREBLE 0 298c2ecf20Sopenharmony_ci#define MIN_DIV (MAX_DIV >> PCSP_MAX_TREBLE) 308c2ecf20Sopenharmony_ci 318c2ecf20Sopenharmony_ci/* wild guess */ 328c2ecf20Sopenharmony_ci#define PCSP_MIN_LPJ 1000000 338c2ecf20Sopenharmony_ci#define PCSP_DEFAULT_SDIV (DIV_18KHZ >> 1) 348c2ecf20Sopenharmony_ci#define PCSP_DEFAULT_SRATE (PIT_TICK_RATE / PCSP_DEFAULT_SDIV) 358c2ecf20Sopenharmony_ci#define PCSP_INDEX_INC() (1 << (PCSP_MAX_TREBLE - chip->treble)) 368c2ecf20Sopenharmony_ci#define PCSP_CALC_RATE(i) (PIT_TICK_RATE / CALC_DIV(i)) 378c2ecf20Sopenharmony_ci#define PCSP_RATE() PCSP_CALC_RATE(chip->treble) 388c2ecf20Sopenharmony_ci#define PCSP_MIN_RATE__1 MAX_DIV/PIT_TICK_RATE 398c2ecf20Sopenharmony_ci#define PCSP_MAX_RATE__1 MIN_DIV/PIT_TICK_RATE 408c2ecf20Sopenharmony_ci#define PCSP_MAX_PERIOD_NS (1000000000ULL * PCSP_MIN_RATE__1) 418c2ecf20Sopenharmony_ci#define PCSP_MIN_PERIOD_NS (1000000000ULL * PCSP_MAX_RATE__1) 428c2ecf20Sopenharmony_ci#define PCSP_CALC_NS(div) ({ \ 438c2ecf20Sopenharmony_ci u64 __val = 1000000000ULL * (div); \ 448c2ecf20Sopenharmony_ci do_div(__val, PIT_TICK_RATE); \ 458c2ecf20Sopenharmony_ci __val; \ 468c2ecf20Sopenharmony_ci}) 478c2ecf20Sopenharmony_ci#define PCSP_PERIOD_NS() PCSP_CALC_NS(CUR_DIV()) 488c2ecf20Sopenharmony_ci 498c2ecf20Sopenharmony_ci#define PCSP_MAX_PERIOD_SIZE (64*1024) 508c2ecf20Sopenharmony_ci#define PCSP_MAX_PERIODS 512 518c2ecf20Sopenharmony_ci#define PCSP_BUFFER_SIZE (128*1024) 528c2ecf20Sopenharmony_ci 538c2ecf20Sopenharmony_cistruct snd_pcsp { 548c2ecf20Sopenharmony_ci struct snd_card *card; 558c2ecf20Sopenharmony_ci struct snd_pcm *pcm; 568c2ecf20Sopenharmony_ci struct input_dev *input_dev; 578c2ecf20Sopenharmony_ci struct hrtimer timer; 588c2ecf20Sopenharmony_ci unsigned short port, irq, dma; 598c2ecf20Sopenharmony_ci spinlock_t substream_lock; 608c2ecf20Sopenharmony_ci struct snd_pcm_substream *playback_substream; 618c2ecf20Sopenharmony_ci unsigned int fmt_size; 628c2ecf20Sopenharmony_ci unsigned int is_signed; 638c2ecf20Sopenharmony_ci size_t playback_ptr; 648c2ecf20Sopenharmony_ci size_t period_ptr; 658c2ecf20Sopenharmony_ci atomic_t timer_active; 668c2ecf20Sopenharmony_ci int thalf; 678c2ecf20Sopenharmony_ci u64 ns_rem; 688c2ecf20Sopenharmony_ci unsigned char val61; 698c2ecf20Sopenharmony_ci int enable; 708c2ecf20Sopenharmony_ci int max_treble; 718c2ecf20Sopenharmony_ci int treble; 728c2ecf20Sopenharmony_ci int pcspkr; 738c2ecf20Sopenharmony_ci}; 748c2ecf20Sopenharmony_ci 758c2ecf20Sopenharmony_ciextern struct snd_pcsp pcsp_chip; 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ciextern enum hrtimer_restart pcsp_do_timer(struct hrtimer *handle); 788c2ecf20Sopenharmony_ciextern void pcsp_sync_stop(struct snd_pcsp *chip); 798c2ecf20Sopenharmony_ci 808c2ecf20Sopenharmony_ciextern int snd_pcsp_new_pcm(struct snd_pcsp *chip); 818c2ecf20Sopenharmony_ciextern int snd_pcsp_new_mixer(struct snd_pcsp *chip, int nopcm); 828c2ecf20Sopenharmony_ci 838c2ecf20Sopenharmony_ci#endif 84