Timer and interrupt not above some 29 kHz

The interrupts can't keep up at that rate. You need an interrupt every 8.9375 uS, and it takes around 3 uS to set and and leave an interrupt. Then there is the time taken to read the pin, toggle it, and write it again.

This code generates 56 kHz on pin 9 using the timer but the hardware toggling (no interrupts):

const byte LED = 9;

void setup() {
  pinMode (LED, OUTPUT);
  
  // set up Timer 1
  TCCR1A = _BV (COM1A0);  // toggle OC1A on Compare Match
  TCCR1B = _BV(WGM12) | _BV(CS10);   // CTC, no prescaler
  OCR1A =  142;       // compare A register value (143 * clock speed)
}  // end of setup

void loop() { }

If you do direct port manipulation you can just squeeze it in, in time, using an interrupt:

#define ledPin 12

void setup()
{
  pinMode(ledPin, OUTPUT);
  
  // initialize timer1 
  TCCR1A = 0;
  TCCR1B = 0;
  TCNT1  = 0;

  TCCR1B |= (1 << WGM12);   // CTC mode
  TCCR1B |= (1 << CS10);    // no prescaler 
  TIMSK1 |= (1 << OCIE1A);  // enable timer compare interrupt
  OCR1A = 142;            // compare match register =16MHz/1/56kHz/2 -1 (troggle) = 142

}

ISR(TIMER1_COMPA_vect)          // timer compare interrupt service routine
{
  if (PINB & _BV (4))
    PORTB &= ~_BV (4);
  else
    PORTB |= _BV (4);
}

void loop()
{
  // your program here...
}

digitalRead and digitalWrite are functions (which have an overhead to call) plus they do a table lookup to convert the pin number to the bit number. By doing it yourself you are saving some time.